Laravel - 查询生成器来选择具有独特的列值(从另一列具有最大值)

问题描述:

多行我有这样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'的唯一值。我如何构建这个查询?

+0

我试过使用 - > max('usage_hour')但是失败,发生分组错误:7 –

试试这个,让我们看看怎么回事

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

错误。它会产生一个错误'错误:列“table_name.data”必须出现在GROUP BY子句中或用于聚合函数中# – AlexM

+0

然后我猜你正在使用mysql 5.7。它的sql_mode更严格。它在我的机器上工作。我改变了我的sql_mode。 – oseintow

+0

其实我们在讨论'postgresql'。但是我在'sqlfiddle'中检查了你的查询,并且它产生了错误的结果。 http://sqlfiddle.com/#!2/bb0ae/1 – AlexM

首先,你需要知道如何做到这一点在普通的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 

如果有人知道没有子查询和窗口功能的方法,请让我知道。