如果我要存储我的用户分数这样:
+---------+-------+------------+
| 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中获得"选择列表的表达式"。在这种情况下,如何按user_id
进行分组?
(我也在使用学说,因此,如果有某种方法可以使用DQL或学说函数实现此目的,也将也有用)
好的,所以您知道如何获得日期差异,并且只需要特定用户的最佳结果,按日期差异订购:
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的最小差异。通过将其作为子查询运行,并将其连接回您已经生成的数据,内部连接将滤除所有行,而差异不等于最小值diff
的所有行,如果用户有一个日期和相同差异之后的日期(即-1和 1 - 它们都是最近的),您可能仍然会为用户重复行。这样,就像选择最大得分