上周,我试图发布一个最受欢迎的帖子。我已创建此 sqlfiddle 以便更好地理解和帮助。
在此sqlFiddle中,您可以看到结果。但是结果是错误的,因为查询会根据所有数据计算出最受欢迎的喜欢的帖子。我想获得上周最受欢迎的喜欢的帖子。有什么问题,查询中的解决方案是什么。任何人都可以帮助我吗?
SELECT
t1.yearweek,
t1.post_id_fk,
t1.liked_post_type,
t1.cnt
AS max_count
FROM
(SELECT
YEARWEEK(FROM_UNIXTIME(liked_time)) AS
yearweek,
post_id_fk,
liked_post_type,
COUNT(*) AS cnt
FROM post_like
GROUP BY
YEARWEEK(FROM_UNIXTIME(liked_time)),post_id_fk,liked_post_type) t1
INNER JOIN
(SELECT yearweek, MAX(cnt) AS max_cnt
FROM
(SELECT YEARWEEK(FROM_UNIXTIME(liked_time)) AS
yearweek,
post_id_fk,
liked_post_type,
COUNT(*) AS cnt
FROM post_like
GROUP BY
YEARWEEK(FROM_UNIXTIME(liked_time)),post_id_fk,liked_post_type) t
GROUP BY yearweek) t2 ON
t1.cnt = t2.max_cnt AND liked_post_type = 'p_image' ORDER BY t2.max_cnt DESC LIMIT 1
CREATE TABLE `post_like` (
`like_id` int(11) NOT NULL,
`post_id_fk` int(11) NOT NULL,
`liked_uid_fk` int(11) NOT NULL,
`liked_post_type` enum('p_text','p_image','p_link','p_video','p_audio','u_following','u_send_friend_request','p_avatar','p_cover','p_gif','p_location','p_watermark','p_which','p_page','p_event','p_blog','p_group') DEFAULT NULL,
`liked_time` int(11) NOT NULL DEFAULT 1524910573
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Tablo döküm verisi `dot_post_like`
--
INSERT INTO `post_like` (`like_id`, `post_id_fk`, `liked_uid_fk`, `liked_post_type`, `liked_time`) VALUES
(2, 7, 4, 'p_image', 1565082347),
(3, 8, 4, 'p_image', 1565082347),
(4, 5, 4, 'p_image', 1565082347),
(5, 3, 4, 'p_image', 1565082347),
(6, 99, 4, 'p_image', 1565082347),
(7, 12, 4, 'p_image', 1533513600),
(8, 7, 4, 'p_image', 1565082347),
(9, 7, 4, 'p_image', 1568351373),
(10, 7, 4, 'p_image', 1568351373),
(11, 7, 4, 'p_image', 1568351373),
(12, 12, 4, 'p_image', 1533513600),
(13, 12, 4, 'p_image', 1533513600),
(14, 12, 4, 'p_image', 1533513600),
(15, 11, 4, 'p_image', 1568351373),
(16, 12, 4, 'p_image', 1533513600);
# The post_id_fk 12 time is last year not this year. That is why this is wrong result.
答案 0 :(得分:3)
您有比实际需要更复杂的联接子查询。确定子查询的最简单的一周是最简单的:
SELECT MAX(YEARWEEK(FROM_UNIXTIME(liked_time))) FROM post_like
可以在INNER JOIN
子句中与FROM
一起加入
SELECT
t1.yearweek,
t1.post_id_fk,
t1.liked_post_type,
t1.cnt AS max_count
FROM
(
-- subquery returns ONLY the most recent week
SELECT
MAX(YEARWEEK(FROM_UNIXTIME(liked_time))) AS lastweek
FROM post_like
) lastweek
-- Joins against subquery that returns likes per week
INNER JOIN (
SELECT
YEARWEEK(FROM_UNIXTIME(liked_time)) AS yearweek,
post_id_fk,
liked_post_type,
COUNT(*) AS cnt
FROM post_like
WHERE liked_post_type = 'p_image'
GROUP BY
YEARWEEK(FROM_UNIXTIME(liked_time)),
post_id_fk,
liked_post_type
) t1 ON lastweek.lastweek = t1.yearweek
-- Retrieve only the top one
ORDER BY max_count DESC LIMIT 1
example here现在返回post_id_fk = 7
,并且在201936
的一周中有3个赞
通过将其放入WHERE IN()
可以更轻松地完成此操作,但是我不确定哪种方法会更有效。
SELECT
YEARWEEK(FROM_UNIXTIME(liked_time)) AS yearweek,
post_id_fk,
liked_post_type,
COUNT(*) AS cnt
FROM post_like
WHERE
liked_post_type = 'p_image'
-- Filter the rows for the most recent week in WHERE
YEARWEEK(FROM_UNIXTIME(liked_time)) IN (SELECT MAX(YEARWEEK(FROM_UNIXTIME(liked_time))) FROM post_like)
GROUP BY
YEARWEEK(FROM_UNIXTIME(liked_time)),
post_id_fk,
liked_post_type
ORDER BY cnt DESC LIMIT 1
此example还会返回post_id_fk = 7
,上周有3个赞。
如果您仍然需要知道该帖子在总体上收到了多少赞,而不仅仅是上周收到了多少,请加入未经YEARWEEK()
过滤的完整分组中
SELECT post_id_fk, COUNT(*) as all_likes FROM post_like GROUP BY post_id_fk
产生:
SELECT
t_week.yearweek,
t_week.post_id_fk,
t_week.liked_post_type,
-- Likes from last week
t_week.cnt AS week_like_count,
-- Likes from all time
t_total.total_likes
FROM
(
SELECT
YEARWEEK(FROM_UNIXTIME(liked_time)) AS yearweek,
post_id_fk,
liked_post_type,
COUNT(*) AS cnt
FROM post_like
WHERE
YEARWEEK(FROM_UNIXTIME(liked_time)) IN (SELECT MAX(YEARWEEK(FROM_UNIXTIME(liked_time))) FROM post_like)
AND liked_post_type = 'p_image'
GROUP BY
YEARWEEK(FROM_UNIXTIME(liked_time)),
post_id_fk,
liked_post_type
) t_week
-- Join on a subquery that returns total likes overall (not just last week)
INNER JOIN (
SELECT post_id_fk, COUNT(*) AS total_likes FROM post_like GROUP BY post_id_fk
) t_total ON t_week.post_id_fk = t_total.post_id_fk
ORDER BY cnt DESC LIMIT 1