Alright so I have a table of items where duplicate items can exist with the same 'parent_uuid' that can be 'published' or 'discarded'. I'm trying to get a 'discarded' group of items, where published is 0 but where there is not a duplicate row with the same 'parent_uuid' that has published marked 1.
When I write the query in sql, it behaves correctly:
SELECT * FROM `items` AS `items` WHERE `published` = 0 AND `created_at` < '2015-08-30 17:23:29' AND NOT EXISTS (SELECT 1 FROM `items` AS `check` WHERE `check`.`parent_uuid` = `items`.`parent_uuid` AND `published` = 1) GROUP BY `parent_uuid`
My test cases return as I expect them to be. When I write this in Laravel query builder like this:
$discarded = self::from('items as items')
->where('published', 0)
->where('created_at', '<', Carbon::now()->subMonth()->toDateTimeString())
->whereNotExists(function($query) {
$query->select(DB::raw(1))
->from('items as check')
->where('check.parent_uuid', 'items.parent_uuid')
->where('published', 1);
})
->groupBy('parent_uuid');
I get more results than I'm supposed to. I get results for items that should fail the where not exists subquery. When I output the last query, it all looks fine. And if I copy this query into my sql client and swap in the variables, it works as I expect it to.
array (size=3)
'query' => string 'select * from `items` as `items` where `published` = ? and `created_at` < ? and not exists (select 1 from `items` as `published` where `published`.`parent_uuid` = ? and `published` = ?) group by `parent_uuid`' (length=211)
'bindings' =>
array (size=4)
0 => int 0
1 => string '2015-08-30 17:23:29' (length=19)
2 => string 'items.parent_uuid' (length=22)
3 => int 1
'time' => float 442.8
I'm unsure what I'm doing wrong and I've tried just about everything I can think of.
Does anyone know what might be going on here? I'm on Laravel 4.2.