我需要确定给定行的日期是否超过一年signed_out
或signed_in
。有时可能会签署一个由NULL
值指定的区域。如果是这种情况,我需要查看下一个最高signed_in
值,以确定该区域是否已在一年内退出。否则,我需要查看每个组的最后signed_in
日期以确定这一点。
这些群组基于territory_id
列。
我的表:
-----------------------------------------------------------------
| id | territory_id | signed_out | signed_in |
-----------------------------------------------------------------
| 5 | 8 | 2012-12-09 00:00:00 | 2013-02-28 00:00:00 |
| 9 | 8 | 2014-03-23 14:48:17 | 2014-06-11 00:00:00 |
| 11 | 10 | 2014-06-25 11:07:59 | NULL |
| 14 | 10 | 2012-06-27 21:28:17 | 2012-10-10 00:00:00 |
| 15 | 11 | 2014-06-27 21:28:48 | NULL |
| 13 | 11 | 2012-09-12 20:23:07 | 2012-12-27 00:00:00 |
| 20 | 11 | 2011-10-30 21:05:29 | 2012-01-05 00:00:00 |
-----------------------------------------------------------------
预期结果:行9
,11
,15
我已经查看了group by
和greatest-n-per-group
标记的mysql问题的许多示例,但我无法理解如何构建此查询,尤其是在Laravel
中使用Eloquent或流利。如果我必须使用Raw查询,我猜这很好。
我尝试了什么:
TerritoriesSignInOut::where('signed_in', '<=', Carbon::now()->subYear())
->orWhere(function($query)
{
$query->where('signed_out', '<=', Carbon::now()->subYear())
->whereNull('signed_in');
})
->groupBy('territory_id')
->orderBy('signed_in', 'DESC')
->get();
但是这不会执行正确的子查询选择,这就是我认为该问题与该声明的关系。
任何帮助都非常受欢迎,因为我已经在脑子里绞尽脑汁待了好几个小时。
答案 0 :(得分:3)
我相信这个查询应该适合你,不过你可能想先测试一下。它似乎对我提供的数据很有用。
SELECT id, GREATEST(signed_in, COALESCE(signed_out, signed_in)) AS `my_date`
FROM (SELECT * FROM `territories` ORDER BY signed_in DESC) territories
GROUP BY territory_id
HAVING my_date <= DATE_SUB(NOW(), INTERVAL 1 YEAR);
要在Fluent中构建查询,这应该可行。它使用了相当多的原始数据,但我认为如果你没有绑定任何数据,就没有注入的机会。
DB::table(DB::raw('(SELECT * FROM `territories` ORDER BY signed_in DESC) territories'))
->select(DB::raw('id, GREATEST(signed_in, COALESCE(signed_out, signed_in)) AS `my_date`'))
->groupBy('territory_id')
->having('my_date', '<=', DB::raw('DATE_SUB(NOW(), INTERVAL 1 YEAR)'))
->get();
你必须更改表的名称,我只是使用了地区,因为它很容易,但它显然不是地区表。