好的,所以我有一个项目表,其中重复的项目可以存在相同的' parent_uuid'可以发布的#39;或者'丢弃'。我试图让一个被丢弃的'一组项目,其中发布的是0但是没有重复的行具有相同的' parent_uuid'已发布标记为1。
当我在sql中编写查询时,它的行为正确:
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`
我的测试用例按照我的预期返回。当我在Laravel查询构建器中写这样:
$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');
我得到的结果比我应该的更多。我得到的项目应该失败的地方不存在子查询。当我输出最后一个查询时,一切看起来都很好。如果我将这个查询复制到我的sql客户端并交换变量,它就像我期望的那样工作。
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
我不确定自己做错了什么,而且我已经尝试过我能想到的一切。
有谁知道这里会发生什么?我在Laravel 4.2上。
答案 0 :(得分:2)
问题似乎与Laravel的查询构建器有关,可能与数据库驱动程序有关。对于我目前拥有的库的构建,这可能是一个暂时的问题。
我发现这些情况的解决方案是创建原始数据库字符串并将其传递到高级where select查询。你可以这样做:
$where_not_exists = '1 FROM `items` AS `check` WHERE `check`.`parent_uuid` = `items`.`parent_uuid` AND `published` = 1';
$discarded = Items::from('items as items')
->where('published', 0)
->where('created_at', '<', Carbon::now()->subMonth()->toDateTimeString())
->whereNotExists(function($query) use ($where_not_exists) {
$query->select(DB::raw($where_not_exists));
})
->groupBy('parent_uuid');
if ($count === TRUE) {
return $discarded->count();
}
return $discarded->get();
它并不是非常难以理解。请务必不要直接将用户发送的输入注入这些内容!