我有以下内容:
user_id date_created project_id
3 10/10/2013 1
3 09/10/2013 1
5 10/10/2013 1
8 10/10/2013 1
10 10/10/2013 1
3 08/10/2013 1
我想要的最终结果是:
user_id date_created project_id
3 10/10/2013 1
5 10/10/2013 1
8 10/10/2013 1
10 10/10/2013 1
上下文
我将这个东西称为影响力,用户可以对项目产生很多影响。 我想获得用户对项目的最新影响列表。
我试过了:
select * from influences
where project_id = 1
group by user_id
ORDER BY created_at DESC
但当然这会忽略用户创建的第一个排序,然后排序完整列表。它只是简单地搜索用户并订购结束列表
LARAVEL - 提供答案的雄辩是这样的:
return Influence::select( "user_id", "influence", DB::raw( "MAX(created_at) as created_at" ) )
->where( "project_id", "=", $projectID )
->groupBy( "user_id", "project_id" )->get();
答案 0 :(得分:4)
您不希望在group by
之前订购,因为根据您的查询结构,您无需按照自己的意愿行事。
如果您想要最近创建的影响力,请明确说明:
select i.*
from influences i join
(select user_id, max(created_at) as maxca
from influences i
where project_id = 1
group by user_id
) iu
on iu.user_id = i.user_id and iu.maxca = i.created_at
where i.project_id = 1;
您的意图是使用文档显式警告使用的MySQL扩展。您希望在select
中添加不在group by
中的列。正如documentation所说:
MySQL扩展了
GROUP BY
的使用范围,以便选择列表可以参考 未在GROUP BY
子句中命名的非聚合列。这意味着 前面的查询在MySQL中是合法的。您可以使用此功能 通过避免不必要的列排序来获得更好的性能 分组。但是,这主要适用于每个中的所有值GROUP BY
中未命名的非聚合列对于每个列都是相同的 组。 服务器可以自由选择每个组中的任何值,所以 除非它们相同,否则所选择的值是不确定的。 此外,不能从每个组中选择值 受添加ORDER BY子句的影响。对结果集进行排序 选择值后发生,ORDER BY不影响 服务器选择的每个组中的值。
答案 1 :(得分:1)
使用此:
SELECT user_id, project_id, MAX(date_created) as latest
FROM influences
WHERE project_id = 1
GROUP BY user_id, project_id
工作原理:MySQL选择符合WHERE
条件的所有行,然后按user_id
对其进行排序,然后按user_id
为每个project_id
排序。从具有相同user_id
和project_id
的每组行中,它将在最终结果集中生成一行。
您可以在SELECT
子句中使用GROUP BY
子句中使用的列(user_id
和project_id
);它们的值是明确的:每个组中的所有行都具有相同的user_id
和project_id
。
您也可以使用aggregate functions。它们中的每一个都使用组中所有行中的一列来计算单个值。最近的created_at
当然是MAX(created_at)
。
如果选择既未包含在GROUP BY
子句中的列,也未传递给聚合函数(如查询中的created_at
),则MySQL没有提示如何计算该值。标准SQL
禁止它(查询无效)但MySQL allows it。它只会从该列中选择一个值,但无法从特定行中选择它,因为这实际上是未定义的行为。
您可以省略project_id
子句中的GROUP BY
,因为WHERE
子句会使所有行具有相同的project_id
。即使project_id
未出现在GROUP BY
子句中并且不使用聚合函数计算,这也会巧合地使结果正确。
我建议您将project_id
保留在GROUP BY
子句中。它不会影响结果或查询速度,它允许您放宽过滤条件(fe使用WHERE project_id IN (1, 2)
)始终获得正确的结果(如果从GROUP BY
中删除它,则不会发生这种情况)。