Select records where not in relational table - laravel

I have 2 tables with this structures :
**table1**
id | title
-----+--------
1 | Blah1
2 | Blah2
**table2**
id | table1_id | article_id
-----+-------------+------------
1 | 1 | 1
2 | 1 | 3
3 | 2 | 1
Now I want to know how can I select all records from table1 where not use in table2
for example I need all table1 records where not exists in table2 for article_id=3
How can I create model and use eloquent models ?
UPDATE:
I need Blah2 from table1 and then show to my user, because Blah1 inserted for article_id = 3 before.
UPDATE 2:
This is worked query, I need write model for this query:
SELECT a.*
FROM table1 AS a
WHERE a.id NOT IN (SELECT table1_id
FROM table2
WHERE article_id = 3
)

you need to create model something like below you can change name appropriately
here i will refer something like below
table1 => ParentModel and table2 => ChildModel
define relation for children in ParentModel with below method
class ParentModel extends Model {
public function children() {
return $this->hasMany(ChildModel::class, 'table1_id');
}
}
whereDoesntHave method is available to filter records with related model
check here https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-absence
ParentModel::whereDoesntHave('children', function($q){
// here $q refers to related model in this case ChildModel
$q->where('article_id', 3);
})->get();
above query should return the required results.

Related

How to write laravel query with left join and a inner join?

I have following tables, and want to do left join with a condition and another inner join from the left joined table,
User table
id | name
1 john
2 sam
3 cecil
Roles table
id | name
1 admin
2 editor
model_has_roles table
role_id | model_type | model_id
1 App\User 1
2 App\User 2
What I want
Do a left join between user table and model_has_roles table on user.id and model_has_roles.model_id column, if model_type is 'App\User' and then another inner join between Roles table and model_has_roles table for role_id and Roles.id column. So result should be like this,
id | name | role
1 john admin
2 sam editor
3 cecil -
I tried following query but not working correctly,
DB::table('users')->select('id', 'name', 'email', 'created_at', 'role_id')
->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
->where('model_has_roles.model_type', '=', 'App\User')
->paginate(1);
If you can please help me to write an eloquent query for this.
Thanks
P.S: Actually, I'm using spatie/laravel-permission, and trying to get all the users with their role name.
This should work just fine:
App\User::with('roles')->get();

Laravel how to get values from a table with an id from another table

i am having some trouble getting results from a query. it's the following. I have two tables, tasks and task_interactions. the table tasks stores the tasks, and the table task_interactions stores the history of the tasks, like a change of status, comments... The column task_id in the task_interactions table is the id in the table tasks.
The table tasks has the following columns: id | project_id | task_type_id | related_block | created_by | assigned_to | start_date | due_date | task_priority | comments | status | created_at |updated_at The status in this table will be deleted.
The table taskinteractions has the following columns:
id,task_id,status,comments,created_at
In the models i have created the following relationships:
Task Model:
public function taskinteractions()
{
return $this->hasMany('App\Taskinteraction');
}
Taskinteraction Model:
public function tasks()
{
return $this->belongsTo('App\Task');
}
And now the question:
I want to get all the tasks assigned to the authenticated user with status (in the table taskinteractions) equal to "In Progress".
I have tried a lot of different approaches with no good results.
I am a newbie and so i believe that the solution might be simple, but i no idea how to do it.
Assuming assigned_to has the id of the user and a typical user table, try the following,$tasks is the array of tasks you want to get
$interactions = TaskInteractions::where('status','In Progress')->get();
$tasks = array();
foreach($interactions as $interaction){
$task = $interaction->task;
if((!(in_array($task, $tasks))) && (Auth::user()->id == $task->assigned_to) ){
array_push($tasks,$task);
}

Oracle Join Two Queries With Distinct Answer

I need help in linking two tables together to bring back data as I need.
I have two queries:
The first is as follows:
SELECT
POI.PO_ID as PO_ID, SUM(POI.INV_QTY) AS INV_QTY, POI.INV_NUMBER,
PO.SUP_SUP_ID AS SUPPLIER
FROM TABLE1 POI, PUR_ORDS PO
WHERE POI.PO_ID = '56886' AND POI.PO_ID = PO.PO_ID
GROUP BY POI.PO_ID, POI.INV_NUMBER, PO.SUP_SUP_ID
ORDER BY POI.INV_NUMBER ASC
The Results of this query are as follows:
PO_ID|INV_QTY|INV_NUMBER|SUPPLIER
---------------------------------
56886| 105|INV1 |SUP1
56886| 106|INV2 |SUP1
The second query I have is this:
SELECT
DIL.PO_PO_ID, sum(DIL.ACPTD_QTY) as ACPTD_QTY,
DIL.DLVD_DLVY_NUMB AS DEL_NUM
FROM TABLE2 DIL
where DIL.PO_PO_ID = '56886'
GROUP BY PO_PO_ID, DIL.DLVD_DLVY_NUMB
order by del_num
The Results of this query are as follows:
PO_PO_ID|ACPTD_QTY|DEL_NUM
--------------------------
56886| 105| 1
56886| 106| 2
Now I am attempting to join the two tables, but I get multiple values appearing, using the following:
SELECT DISTINCT(PO_ID), INV_NUMBER, INV_QTY, SUPPLIER, ACPTD_QTY, DEL_NUM
FROM
(SELECT
SELECT POI.PO_ID as PO_ID, SUM(POI.INV_QTY) AS INV_QTY,
POI.INV_NUMBER, PO.SUP_SUP_ID AS SUPPLIER
FROM TABLE1 POI, PUR_ORDS PO
WHERE POI.PO_ID = '56886'
AND POI.PO_ID = PO.PO_ID
GROUP BY POI.PO_ID, POI.INV_NUMBER, PO.SUP_SUP_ID
ORDER BY POI.INV_NUMBER ASC) POINET
INNER JOIN
(SELECT DIL.PO_PO_ID, sum(DIL.ACPTD_QTY) as ACPTD_QTY,
DIL.DLVD_DLVY_NUMB AS DEL_NUM
FROM TABLE 2 DIL
where DIL.PO_PO_ID = '56886'
GROUP BY PO_PO_ID, DIL.DLVD_DLVY_NUMB
order by DEL_NUM) DILV
ON DILV.PO_PO_ID = POINET.PO_ID
GROUP BY PO_ID, INV_NUMBER, INV_QTY, SUPPLIER, ACPTD_QTY, DEL_NUM
ORDER BY INV_NUMBER
However the dataset I get is this:
PO_ID|INV_NUMBER |INV_QTY|SUPPLIER|ACPTD_QTY|DEL_NUM
-----------------------------------------------------
56886|K-101/2014-15| 105|SUP1 | 105| 1
56886|K-101/2014-15| 105|SUP1 | 106| 2
56886|K-107/2014-15| 106|SUP1 | 105| 1
56886|K-107/2014-15| 106|SUP1 | 106| 2
However I need it show the following:
PO_ID|INV_NUMBER |INV_QTY|SUPPLIER|ACPTD_QTY|DEL_NUM
------------------------------------------------------
56886|K-101/2014-15| 105|SUP1 | 105| 1
56886|K-107/2014-15| 106|SUP1 | 106| 2
What do I need to do, to tweak my query?
Any help would be much appreciated.
I think you just need to modify your join statement to join on both columns
ON DILV.PO_PO_ID = POINET.PO_ID
AND DILV.INV_QTY = POINET.ACPTD_QTY
Actually, you can probably leave out the PO_ID, because I it's the same in both subqueries:
i.e. Just do this (on the third last line):
ON DILV.INV_QTY = POINET.ACPTD_QTY

Laravel 4 - Simple join with Eloquent?

I'm simply trying to join 2 tables with Laravel 4's Eloquent ORM. The tables are:
TABLE: PRODUCTS
ID | CATEGORY_ID | NAME
-------------------------
1 | 2 | Hammer
2 | 2 | Saw
3 | 1 | Apple
TABLE: CATEGORIES
ID | NAME
-----------
1 | Food
2 | Tools
Of course this can be done with SQL:
SELECT products.name, categories.name
FROM products
INNER JOIN categories ON products.category_id = categories.id
And this will output:
Hammer | Tools
Saw | Tools
Apple | Food
But is there an easier way to get the same result using Laravel's Eloquent, maybe using the build-in table relationships?
Set up a many-to-one relation in your models:
Category.php
public function products() {
return $this->hasMany('Product');
}
Product.php
public function category() {
return $this->belongsTo('Category');
}
Then call:
$products = Product::with('category')->get();
For each element of the result, $products->name and $products->category->name will contain your fields.

Distinct query in Criteria NHibernate

I need the corresponding query in Criteria language to this one (to retrieve all categories from my table but to distinct them):
SELECT DISTINCT categoryName
FROM Category
WHERE CategoryID IN (
SELECT CategoryID
FROM FoodCategory
)
ORDER BY categoryName
I have table FoodCategory table
id | FoodID | CategoryID
--------|---------------|------------
| |
| |
| |
Actually CategoryID is a foreign key that is pointing to this table here. This is table for Category:
CategoryID | categoryName | otherField
---------------|------------------|------------
| |
| |
| |
And this is table for Food:
FoodID | FoodName | otherField
---------------|------------------|------------
| |
| |
| |
Something like that should do the trick :
public List<String> retrieveFoodCategoryNames() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteriaQuery = builder.createQuery(String.class);
Root<FoodCategory> root = criteriaQuery.from(FoodCategory.class);
// by default an inner join so it will only get the categories which have their id in the FoodCategory table
Join<FoodCategory, Category> joinCategory = root.join(FoodCategory_.category);
Fetch<FoodCategory, Category> fetchCategory = root.fetch(FoodCategory_.category);
Path<String> categoryNamePath = fetchCategory.get(Category_.categoryName);
criteriaQuery.select(categoryNamePath).distinct(true);
criteriaQuery.orderBy(builder.asc(categoryNamePath));
return entityManager.createQuery(criteriaQuery).getResultList();
}
This is not the exact same SQL request because you used a subquery where I'm using a join but it seemed more suited to this particular case. The subquery syntax is a bit more complex and I will not try to write it without compiling! ^^
If something is unclear let me know :-)

Resources