eloquent where not in query? - laravel-4

I'm trying to build the following sql query with eloquent. The query gives me all records from table_a which are in the list of ids and do not appear in table_b.
select * from table_a
where id in (1,2,3)
and id not in
(select tablea_id from table_b
where tablea_id in (1,2,3))
So how do I do it in eloquent ? I want to avoid using a raw query.
//does not work
TableA::whereIn('id',$ids)
->whereNotIn('id', TableB::select('tabla_id')->whereIn($ids));

To run a subquery you have to pass a closure:
TableA::whereIn('id',$ids)
->whereNotIn('id', function($q){
$q->select('tabla_id')
->from('tableb');
// more where conditions
})
->get();

Related

GraphQL Where Select Sub Query

These day, i have studied GraphQL with Laravel framework, Lighthouse Library.
I have tried to do kind of SELECT Query.
As a result, I wonder GraphQL can select below SQL Query
SELECT * FROM TABLE_A WHERE type=1 AND chart_id=(SELECT id FROM TABLE_B WHERE phone='0000~~')
I expect, Client first get result from this query.
SELECT id FROM TABLE_B WHERE phone='0000~~'
And then Do Second query, i think i can get a result.
But i wonder I can get result from 1 request. Thanks.
You can try following
$phoneNumber = '0000~~';
$data = DB::table('tableA')->where('type',1)
->whereIn('chart_id',function($query) use ($phoneNumber) {
$query->select('id')
->from('tableB')
->where('phone', '=',$phoneNumber);
})->get();
If there is relationship between tableA and tableB you can do following
TableA::where('type',1)
->whereHas('tableBRelationshipName', function ($q) use ($phoneNumber) {
$q->select('id')
$q->where('phone','=',$phoneNumber);
})->get();

Laravel Eloquent how to query with multiple 'froms'?

How do I convert a query like this to eloquent:
select table1.column, table2.column, table3.column from table1, table2, table3
You can use achieve this by
DB::query()
->from('table1, table2, table3')
->select('table1.column', 'table2.column', 'table3.column')
->get()
You can use fromRaw():
DB::query()
->select('table1.column', 'table2.column', 'table3.column')
->fromRaw('table1, table2, table3')
->get();

Laravel Eloquent - Eager Loading Query is Being Restricted by limit()

I have the following query:
MyTable::where('my_column', '=', 25)->with('myOtherTable')
->orderBy('id', DESC)->limit(5);
I would like the above to bring me results analogoous to the following raw SQL query:
SELECT *
FROM myTable AS ABB1
LEFT JOIN myOtherTable AS ABB2 ON ABB1.id = ABB2.myTable_id
WHERE my_column = 25
ORDER BY myTable.id DESC
LIMIT 5;
The above will find everything in myTable along with corresponding info from myOtherTable and then limit the results to 5 rows.
When I run the eloquent statement above, two SQL queries are processed. The first looks something like:
SELECT *
FROM myTable
WHERE my_column = 25
ORDER BY id DESC;
If this query returns say 7 result items, but I pass in a smaller number into the limit() function (ie. limit(5)), then the corresponding eager loading query will look like:
SELECT *
FROM myOtherTable
WHERE id IN(1, 2, 3, 4, 5);
The eager loading query is itself limited to 5 items. There should be no limit here. The number of items in the IN conditional above should be 7 (or whatever the count returned from the first query is). The limit should only be applied after the second query runs.
How would I do this with Eloquent?
You can use eloquent's join.
MyTable::join('myOtherTable', 'column_id', '=', 'id')
->where('my_column', '=', 25)
->with('myOtherTable')
->orderBy('id', DESC)
->limit(5);
The with is only if you want to eager load the relation on MyTable.

Sub-queries in Laravel

I have a query in MySQL
SELECT * FROM group_recordings WHERE id IN ( SELECT MAX(id) FROM group_recordings GROUP BY time_span )
there is a sub-query in "IN" operator, I want to convert this query in laravel eloquent, I have GroupRecording Model. Anyone help me with that
I think the Laravel style of such query will be,
GroupRecording::whereIn('id', function($query) {
$query->selectRaw('MAX(id)')
->from('group_recordings')
->groupBy('time_span');
})
->where('time_span', '>', $recording->time_span)
->get();

Converting a raw query to Laravel query builder

I have the following MySQL query which fetches a list of the last 9 authors to write a post and lists them in order of the date of the last post they wrote.
It's working properly but I'd like to re-write it using the Laravel Query Builder. Here is the query at the moment:
$authors = DB::select("
SELECT
`a`.`id`,
`a`.`name`,
`a`.`avatar`,
`a`.`slug` AS `author_slug`,
`p`.`subheading`,
`p`.`title`,
`p`.`slug` AS `post_slug`,
`p`.`summary`,
`p`.`published_at`
FROM
`authors` AS `a`
JOIN
`posts` AS `p`
ON `p`.`id` =
(
SELECT `p2`.`id`
FROM `posts` AS `p2`
WHERE `p2`.`author_id` = `a`.`id`
ORDER BY `p2`.`published_at` DESC
LIMIT 1
)
WHERE
`a`.`online` = 1
ORDER BY
`published_at` DESC
LIMIT 9
");
I understand the basics of using the query builder, but there doesn't appear to be anything in the Laravel docs that allows for me to JOIN a table ON a SELECT.
Can anyone suggest a way that I can write this query using the Laravel Query builder, or perhaps suggest a way that I can rewrite this query to make it easier to structure with the query builder?
Try to do like this
$data = DB::table('authors')
->select(
'a.id',
'a.name',
'a.avatar',
'a.slug AS author_slug',
'p.subheading',
'p.title',
'p.slug AS post_slug',
'p.summary',
p.published_at')
->from('authors AS a')
->join('posts AS p', 'p.id', '=', DB::raw("
(
SELECT p2.id FROM posts AS p2
WHERE p2.author_id = b.id
ORDER BY p2.published_at
DESC LIMIT 1
)"))
->where('a.online', 1)
->limit(9)
->orderBy('p.published_at', 'desc')
->get();

Resources