Laravel - 查询构建器,用于选择具有唯一列值的多行(具有来自另一列的最大值)

时间:2016-03-03 22:12:09

标签: database postgresql laravel

我有一张这样的表

data | usage_date | usage_hour
x    | 03/03/2016 | 05:30:30
y    | 03/02/2016 | 11:30:30
z    | 03/03/2016 | 07:30:30
p    | 03/02/2016 | 05:30:30

当我运行Laravel查询时,我希望看到以下行被选中

y    | 03/02/2016 | 11:30:30
z    | 03/03/2016 | 07:30:30

所以基本上我想建立一个查询,它会为' usage_date'提供唯一的值,其中包含max' usage_hour'。如何构建此查询?

2 个答案:

答案 0 :(得分:0)

试试这个,看看它是怎么回事

$table = \DB::table('table name')->distinct('usage_date')->groupBy('usage_date')->orderBy('usage_hour','desc')->get();

答案 1 :(得分:0)

首先,您需要知道如何在纯SQL中执行此操作,因为Laravel的QueryBuilder只是用于构建SQL查询的工具。

您描述的任务有点棘手,遗憾的是,没有简短的SQL查询。

可以使用window functions

完成
SELECT DISTINCT usage_date, 
    first_value(usage_hour) OVER (PARTITION BY usage_date ORDER BY usage_hour DESC) as usage_hour, 
    first_value(data) OVER (PARTITION BY usage_date ORDER BY usage_date DESC, usage_hour DESC) as data
FROM t

sqlfiddle example

使用QueryBuilder,它将如下所示:

DB::table('t')
    ->distinct()
    ->select([
        'usage_date',
        DB::raw('first_value(usage_hour) OVER (PARTITION BY usage_date ORDER BY usage_hour DESC) as usage_hour'),
        DB::raw('first_value(data) OVER (PARTITION BY usage_date ORDER BY usage_date DESC, usage_hour DESC) as data')
    ])
    ->get()

或者可以使用子查询(效率低而且不冷却)来完成:

SELECT usage_date, max(usage_hour) as usage_hour,
  (SELECT data FROM t AS t2 
   WHERE t2.usage_date = t.usage_date AND t2.usage_hour = max(t.usage_hour) 
  LIMIT 1) AS data
FROM t
GROUP BY usage_date

如果有人知道没有子查询和窗口函数的方法,请告诉我。