MySQL group by和max返回错误的行

MySQL group by和max返回错误的行,mysql,group-by,greatest-n-per-group,Mysql,Group By,Greatest N Per Group,我有两张桌子,我试图找到每天得分最高的“帖子” CREATE TABLE IF NOT EXISTS `posts_points` ( `post_id` int(10) unsigned NOT NULL, `comments` smallint(5) unsigned NOT NULL, `likes` smallint(5) unsigned NOT NULL, `favorites` smallint(5) unsigned NOT NULL, PRIMARY KE

我有两张桌子,我试图找到每天得分最高的“帖子”

CREATE TABLE IF NOT EXISTS `posts_points` (
  `post_id` int(10) unsigned NOT NULL,
  `comments` smallint(5) unsigned NOT NULL,
  `likes` smallint(5) unsigned NOT NULL,
  `favorites` smallint(5) unsigned NOT NULL,
   PRIMARY KEY (`post_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `posts` (
  `profile_id` int(10) unsigned NOT NULL,
  `post_id` int(10) unsigned NOT NULL,
  `pubdate_utc` datetime NOT NULL,
  PRIMARY KEY (`post_id`),
  KEY `profile_id` (`profile_id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
我试过下面的问题。它返回正确的分数,但其他列只是随机的行。我做错了什么

SELECT p.post_id, p.profile_id
   , MAX(t1.score)
   , DATE_FORMAT(t1.pubdate_utc, '%d %b') post_date
   , DATE(t1.pubdate_utc) mydate
FROM
(
   SELECT p.profile_id, p.post_id, p.pubdate_utc
      , (pp.comments + pp.likes + pp.favorites) AS score
   FROM posts p 
   INNER JOIN posts_points pp ON p.post_id = pp.post_id
) t1
INNER JOIN posts p ON t1.post_id = p.post_id
   AND t1.pubdate_utc = p.pubdate_utc
GROUP BY mydate
ORDER BY mydate DESC
LIMIT 18;
如果按Column1对数据进行排序,则看起来是这样的…..orderby只对第一列进行排序

Column1  Column2
A        any thing
B        z            
C        d
D        y

理解你想做什么有点难

单词(列(帖子、评论、收藏夹)和PK),我知道您更新了值​​增加,不记录每次投票

此选择返回帖子中的数据,并通过排序更大的分数将分数限制为18

        SELECT P.post_id,
               P.profile_id,
               (PP.comments + PP.likes + PP.favorites) AS score,
               DATE_FORMAT (P.pubdate_utc, '%d %b') AS post_data,
               DATE (P.pubdate_utc) AS mydate
          FROM posts P
    INNER JOIN posts_points PP
            ON (= P.post_id PP.post_id)
      ORDER BY 3 DESC
         LIMIT 18;

如果您想选择当天最多的选票,您必须在该表中记录喜欢/喜欢不同、需要的数据(张贴分数)。

哇!棘手的例如,max总是有打领带的可能性

下面的解决方案创建一个当天最高分数的中间列表,然后获取所有分数等于当天最高分数的帖子。它返回平局,因此您可以在给定的一天内得到两行。请原谅,我无法测试这一点,所以请给出反馈,我相信我们可以让这一点满足您的需要

SELECT p.profile_id, p.post_id, p.pubdate_utc
, DATE_FORMAT(p.pubdate_utc, '%d %b') AS post_date
, DATE(p.pubdate_utc) AS mydate
, (pp.comments + pp.likes + pp.favorites) AS score
FROM posts p 
INNER JOIN posts_points pp ON p.post_id = pp.post_id
INNER JOIN 
(
    SELECT p.pubdate_utc AS max_date, 
    (pp.comments + pp.likes + pp.favorites) AS max_score
    FROM posts p2 
    INNER JOIN posts_points pp2 ON p2.post_id = pp2.post_id
) m ON score = m.max_score
AND mydate = m.max_date
ORDER BY mydate DESC
LIMIT 18;

您可以看到此查询。内部查询是首先获取两个表中与sum(pp.comments+pp.likes+pp.favorites)具有相同post_id的行作为分数。外部查询是获取最大分数并按日期进行分组

SELECT post_id, profile_id
   , MAX(score)
   , DATE_FORMAT(pubdate_utc, '%d %b') post_date
   , DATE(pubdate_utc) as mydate
FROM
(
   SELECT p.profile_id, p.post_id, p.pubdate_utc
      , (pp.comments + pp.likes + pp.favorites) AS score
   FROM posts p 
   INNER JOIN posts_points pp ON p.post_id = pp.post_id
) 
GROUP BY pubdate_utc
ORDER BY pubdate_utc DESC

我一直遇到这个问题。当MySQL运行聚合函数时,对于任何未聚合的列,它只提取它为该组运行的第一个数据,不管它是否来自MAX行。因此,您需要做的是对内部查询中的数据进行排序,以便最大值在其组中位于第一位。看看这是否适合您:

SELECT t.post_id,
       t.profile_id,
       t.score,
       t.pubdate_utc
FROM (SELECT p.profile_id,
             p.post_id,
             p.pubdate_utc,
             (pp.comments + pp.likes + pp.favorites) score
      FROM posts p
      JOIN posts_points pp ON p.post_id = pp.post_id
      WHERE p.pubdate_utc >= DATE_ADD(DATE(NOW()), INTERVAL -17 DAY)
      ORDER BY score DESC
     ) t
GROUP BY DATE(t.pubdate_utc) DESC
;
请注意,我在这里没有使用MAX函数。按分数降序排序,然后在外部查询中按日期分组,将按日期获得最高分数。还要注意,我将WHERE子句放在了内部查询中。像这样的内部查询(有时是必要的)效率不高,因为它们没有外部查询的索引可供优化,所以请确保内部结果集尽可能小。最后,请按日期(t.pubdate\u utc)通知该组。如果我不把它减少到仅仅是日期信息,将会有超过18个结果,因为当时也计算了时间


编辑:更改为
INTERVAL-17天
,最多放弃18个结果,而不是19个。

+1因为包含了表格定义,您没有做错任何事情。聚合函数不会影响其他列的值。它们看起来是“随机的”。按日期分组应该会产生这种奇怪的行为。我相信我下面有你的答案。顺便说一句,在CREATETABLE语句中,在KEY子句之后有一个额外的逗号。“posts\u points”是我用来调试和加速事情的摘要表。每一条评论,像和最喜欢的,实际上是分开记录的。看起来您的查询将找到得分最高的帖子。我正在努力寻找过去18天里每天得分最高的帖子。我不知道它是否有意义。你好,它的结构如何?记录的评论/爱好/喜好在哪里?如果有必要,你可以换桌子吗?
SELECT t.post_id,
       t.profile_id,
       t.score,
       t.pubdate_utc
FROM (SELECT p.profile_id,
             p.post_id,
             p.pubdate_utc,
             (pp.comments + pp.likes + pp.favorites) score
      FROM posts p
      JOIN posts_points pp ON p.post_id = pp.post_id
      WHERE p.pubdate_utc >= DATE_ADD(DATE(NOW()), INTERVAL -17 DAY)
      ORDER BY score DESC
     ) t
GROUP BY DATE(t.pubdate_utc) DESC
;