Closed. This question needs details or clarity。它当前不接受答案。
想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
在8个月前关闭。
对于像这样的表:
看起来像
在上述数据集中,匹配发生在userid = 1和userid = 2之间的4/22以及userid = 2和userid = 4之间的4/25
我想编写一个查询,该查询计算每天的共同点赞次数(按日期(点赞时间)分组)。当用户喜欢另一个之前喜欢过他/她的用户时,就会发生相互喜欢。
预期结果应为:
为了验证查询,我选择使用返回明细行的查询(避免使用GROUP BY和聚合函数)
在没有唯一约束的情况下,我们返回的计数可能不是“独特的”相互喜欢的。考虑
查询将返回一个类似的结果集
跟进:
要返回“零”计数,我们可以这样做。将查询包装在括号内,作为内联视图。并将其外部连接到日历行源,该日历行源返回我们要返回的日期值的不同列表,包括没有任何喜欢/喜欢/喜欢的行要计数的日期
好吧,这有点令人困惑。让我们看一下单独的SELECT语句。该内联视图
这就是日期列表,它是“日历”行源。我们可以引用一个“日历”表,以便为我们提供所需的日期。
标记为/别名为
当我们全神贯注于此时,我们看到的实际上是以下形式的查询:
(IFNULL让我们用零替换缺失行中的NULL)
还有其他查询模式会返回等效结果,例如
想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
在8个月前关闭。
对于像这样的表:
CREATE TABLE IF NOT EXISTS `like` (
`liking_user_id` int(6) unsigned NOT NULL,
`liked_user_id` int(6) unsigned NOT NULL,
`like_time` timestamp NOT NULL,
)
看起来像
liking_user_id liked_user_id like_time
1 2 2018-04-18 00:02:07
2 4 2018-04-19 00:09:07
2 1 2018-04-22 00:02:07
4 5 2018-04-23 00:02:07
1 4 2018-04-24 00:02:07
4 2 2018-04-25 00:02:07
在上述数据集中,匹配发生在userid = 1和userid = 2之间的4/22以及userid = 2和userid = 4之间的4/25
我想编写一个查询,该查询计算每天的共同点赞次数(按日期(点赞时间)分组)。当用户喜欢另一个之前喜欢过他/她的用户时,就会发生相互喜欢。
预期结果应为:
date(like_time) as Date count(liking_user_id ...) as Count
2018-04-17 0
2018-04-18 0
2018-04-19 0
2018-04-20 0
2018-04-21 0
2018-04-22 1
2018-04-23 0
2018-04-24 0
2018-04-25 1
最佳答案
没有唯一的约束,并且匹配行的规范为“以前喜欢他/她的人”,
为了避免JOIN中潜在的“重复项”问题,我选择带有相关子查询的EXISTS
来测试具有较早时间戳记的对应行的存在
像这样:
SELECT DATE(t.`like_time`) AS `date_`
, COUNT(1) AS `count_`
FROM `like` t
WHERE EXISTS ( -- corresponding row with earlier timestamp
SELECT 1
FROM `like` f
WHERE f.`liked_user_id` = t.`liking_user_id`
AND f.`liking_user_id` = t.`liked_user_id`
AND f.`like_time` < t.`like_time`
)
GROUP
BY DATE(t.`like_time`)
为了验证查询,我选择使用返回明细行的查询(避免使用GROUP BY和聚合函数)
在没有唯一约束的情况下,我们返回的计数可能不是“独特的”相互喜欢的。考虑
t_id f_id liked_time
---- ---- ----------
66 77 2019-06-01
77 66 2019-06-02
66 77 2019-06-05
77 66 2019-06-05
66 77 2019-06-06
查询将返回一个类似的结果集
date_ count_
---------- ------
2019-06-02 1
2019-06-05 2
2019-06-06 1
跟进:
要返回“零”计数,我们可以这样做。将查询包装在括号内,作为内联视图。并将其外部连接到日历行源,该日历行源返回我们要返回的日期值的不同列表,包括没有任何喜欢/喜欢/喜欢的行要计数的日期
SELECT c.date_
, IFNULL(s.count_,0) AS `count_`
FROM ( SELECT DATE(d.`like_time`) AS `date_`
FROM `like` d
GROUP
BY DATE(d.`like_time`)
) c
LEFT
JOIN ( SELECT DATE(t.`like_time`) AS `date_`
, COUNT(1) AS `count_`
FROM `like` t
WHERE EXISTS ( -- corresponding row with earlier timestamp
SELECT 1
FROM `like` f
WHERE f.`liked_user_id` = t.`liking_user_id`
AND f.`liking_user_id` = t.`liked_user_id`
AND f.`like_time` < t.`like_time`
)
GROUP
BY DATE(t.`like_time`)
) s
ON s.`date_` = c.`date_`
ORDER
BY c.`date_`
好吧,这有点令人困惑。让我们看一下单独的SELECT语句。该内联视图
c
,我们可以单独运行该查询 SELECT DATE(d.`like_time`) AS `date_`
FROM `like` d
GROUP
BY DATE(d.`like_time`)
这就是日期列表,它是“日历”行源。我们可以引用一个“日历”表,以便为我们提供所需的日期。
标记为/别名为
s
的嵌入式视图是问题顶部的查询。当我们全神贯注于此时,我们看到的实际上是以下形式的查询:
SELECT c.date_
, IFNULL(s.count_,0) AS count_
FROM c
LEFT
JOIN s
ON s.date_ = c.date_
ORDER
BY c.date_
(IFNULL让我们用零替换缺失行中的NULL)
还有其他查询模式会返回等效结果,例如
SELECT s.date_
, SUM(s.has_match_) AS count_
FROM ( SELECT DATE(t.like_time) AS date_
, EXISTS ( SELECT 1
FROM `like` f
WHERE f.liked_user_id = t.liking_user_id
AND f.liking_user_id = t.liked_user_id
AND f.like_time < t.like_time
) AS has_match_
FROM `like` t
) s
GROUP
BY s.date_
ORDER
BY s.date_
关于mysql - 在SQL中每天计算用户匹配项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56568225/
10-16 08:39