上周最受欢迎的喜欢的帖子

时间:2019-09-13 05:43:14

标签: mysql sql

上周,我试图发布一个最受欢迎的帖子。我已创建此 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.

1 个答案:

答案 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

Example with total likes and last week likes