MySQL - 按非聚合列分组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL - 按非聚合列分组相关的知识,希望对你有一定的参考价值。
如果我存储我的用户的分数如下:
+---------+-------+------------+
| user_id | score | created_at |
+---------+-------+------------+
| 1 | 100 | 2017-12-20 |
| 1 | 200 | 2017-12-21 |
| 2 | 110 | 2017-12-20 |
| 2 | 210 | 2017-12-21 |
| 3 | 120 | 2017-12-20 |
| 3 | 220 | 2017-12-21 |
+---------+-------+------------+
在给定输入日期的情况下,如何为每个用户获取最接近的记录?
我做得很好
SELECT *, (abs(datediff("$some-input-date", created_at))) as diff FROM table order by diff
这将给我一个输入日期2017-12-19
:
+---------+-------+------------+------+
| user_id | score | created_at | diff |
+---------+-------+------------+------+
| 1 | 100 | 2017-12-20 | 1 |
| 2 | 110 | 2017-12-20 | 1 |
| 3 | 120 | 2017-12-20 | 1 |
| 1 | 200 | 2017-12-21 | 2 |
| 2 | 210 | 2017-12-21 | 2 |
| 3 | 220 | 2017-12-21 | 2 |
+---------+-------+------------+------+
现在我想要user_id
的独特行,所以我假设像GROUP BY user_id
这样的东西可以工作,但我在mysql 5.7中得到“SELECT列表的表达式不在GROUP BY子句中”错误。在这种情况下,我如何按user_id
分组?
(我也在使用doctrine,所以如果有一些方法可以使用dql或doctrine函数来实现这一点,这也很有用)
答案
好的,所以你知道如何获得日期差异,并且你只想要特定用户的最高结果,按日期差异升序排序:
SELECT * FROM
--your current query
(SELECT *, (abs(datediff("$some-input-date", created_at))) as diff FROM table) as data_with_diffs
INNER JOIN
( --a query to find only the minimum diffs per user id
SELECT userID, MIN(abs(datediff("$some-input-date", created_at))) as min_diff
FROM table
GROUP BY userid
) as find_min_diffs
ON
data_with_diffs.userid = find_min_diffs.userid AND
data_with_diffs.diff = find_min_diffs.min_diff
如果您单独运行两个内部查询,您将看到它是如何工作的。还有其他方法来构建这个,但我认为这最适合你根据你不理解/已经开发的东西看看整个事物是如何挂起来的
分组查询仅选择特定用户ID的最小差异。通过将其作为子查询运行,并将其连接回已生成的数据,INNER JOIN将过滤掉diff不等于最小diff的所有行。
你可能仍然会为用户提供重复的行,如果他们有一个日期之前和一个日期之后有相同的差异(即-1和+1 - 这些都是最近的)所以你可能必须实施一个策略来处理它,喜欢挑选他们的MAX分数
以上是关于MySQL - 按非聚合列分组的主要内容,如果未能解决你的问题,请参考以下文章