查询不工作需要在groupby之前命令?

时间:2014-08-28 04:38:16

标签: mysql sql greatest-n-per-group

这应该是一个主题列表,其中贴有新的附件。

此查询中的group by并非如我所愿。 (它是SMF。) 它应该从每个具有最新附件的线程中提取一个代表性附件 - 不仅仅是新线程,而是任何线程。结果将是链接到发布相应新图像的线程的一个缩略图。

相反,它不起作用。它目前有2个问题。第一个问题是它显示了线程中的第一个附件而不是最近的附件。第二个问题是它按线程创建日期排序。我希望附件创建日期为订单,并根据哪些线程中包含最新附件来对线程列表进行排序。因此,即使它具有最近的附件,旧线程也不会升至顶部。我需要先选择子选择吗?我怎样才能做到这一点?

提前非常感谢你。

SELECT *
FROM smf_attachments AS att
    INNER JOIN smf_messages AS m ON (m.id_msg = att.id_msg)
    INNER JOIN smf_topics AS t ON (t.id_topic = m.id_topic)
    LEFT JOIN smf_members AS mem ON (mem.id_member = m.id_member)
    LEFT JOIN smf_attachments AS thumb ON (thumb.id_attach = att.id_thumb)
WHERE att.attachment_type = 0
    AND t.id_board = 3

GROUP BY t.id_topic         
ORDER BY att.id_attach  DESC
LIMIT 2

(编辑)。

假设我们有三个topic_id,每个都有5个附件。较高的附件编号意味着它是较新的附件,较高的topic_id意味着它是一个较新的主题。

topic_id 1|attachment 3,6,13,14,15
topic_id 2|attachment 1,2,4,5,12
topic_id 3|attachment 7,8,9,10,11

在上述情况下,查询应该提取2条记录(限制2):

topic_id  attachment
--------  ----------
1         15
2         12

由于我只想要每个主题1个附件,所以带有最新附件的2个主题是主题1和2(分别带有附件15和12)。尽管主题3是最新的,但在这种情况下它不会是一个结果,因为它的附件较旧。

(编辑)。

我尝试了systemmatrix提供的解决方案,但它仍然按topic_id创建日期排序,而不是哪个主题包含最新的附件。我试图让我的问题更清楚。有帮助吗?提前谢谢。

(编辑) 我现在看到它按每个主题中第一个附件的日期排序。最近的第一个附件的主题。我需要最新附件或最后附件的主题

编辑 我做了一个改变,给了我正确的主题列表。这是新代码。

            SELECT att.id_thumb, att.id_msg, att.attachment_type, att.id_attach, distinct on (t.id_topic)
            FROM smf_attachments AS att
                INNER JOIN smf_messages AS m ON (m.id_msg = att.id_msg)
                INNER JOIN smf_topics AS t ON (t.id_topic = m.id_topic)
                LEFT JOIN smf_members AS mem ON (mem.id_member = m.id_member)
                LEFT JOIN smf_attachments AS thumb ON (thumb.id_attach = att.id_thumb)
            WHERE att.attachment_type = 0
                AND t.id_board = 3


            ORDER BY max(att.id_attach)  DESC
            LIMIT 2

现在唯一的问题是如何让它向我展示正确的缩略图附件?它仍然显示相应主题中的第一个附件而不是最后一个。任何帮助? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

如果这些是唯一的3列,则需要每个主题的最近记录

  • att.id_thumb
  • att.id_msg
  • att.attachment_type

您可以使用SUBSTRING_INDEX优于GROUP_CONCAT的结果,以获取id_thumb排序的主题的最新id_attach,您可以编写表达式id_thumb

SUBSTRING_INDEX(
GROUP_CONCAT(att.id_thumb ORDER BY att.id_attach DESC SEPARATOR '||'),
'||',1) AS id_thumb 

  • GROUP_CONCAT(表达式)
  

这将为主题分组所有id_thumb并为您提供   列表由double ||分隔或者您可以按照更改分隔符   您在上面的需求我使用 || 作为上述结果   函数将像thumb1||thumb2||thumb3||thumb4一样   由id_attach按降序排序。

     

注意结果被截断为group_concat_max_len系统变量给出的最大长度,该变量具有默认值   1024.尽管有效最大值,可以设置更高的值   返回值的长度受值的约束   max_allowed_pa​​cket的。


  • SUBSTRING_INDEX(STR,DELIM,计数)
  

From docs返回count之前字符串str的子字符串   出现分隔符delim。如果数是积极的,那就是一切   最后一个分隔符的左边(从左边算起)是   回。如果计数是负数,那么最后的一切都是正确的   分隔符(从右边开始)返回。 SUBSTRING_INDEX()   搜索delim时执行区分大小写的匹配。


现在您的最终查询将如下所示

SELECT 
SUBSTRING_INDEX(GROUP_CONCAT(att.id_thumb ORDER BY att.id_attach DESC SEPARATOR '||'),'||',1) AS id_thumb,
SUBSTRING_INDEX(GROUP_CONCAT(att.id_msg ORDER BY att.id_attach DESC SEPARATOR '||'),'||',1) AS id_msg,
SUBSTRING_INDEX(GROUP_CONCAT(att.attachment_type ORDER BY att.id_attach DESC SEPARATOR '||'),'||',1) AS attachment_type,
MAX(att.id_attach) AS id_attach_max,
t.id_topic
FROM
  smf_attachments AS att 
  INNER JOIN smf_messages AS m ON (m.id_msg = att.id_msg) 
  INNER JOIN smf_topics AS t ON (t.id_topic = m.id_topic) 
  LEFT JOIN smf_members AS mem ON (mem.id_member = m.id_member) 
  LEFT JOIN smf_attachments AS thumb ON (thumb.id_attach = att.id_thumb) 
WHERE att.attachment_type = 0 
  AND t.id_board = 3 
GROUP BY  t.id_topic
ORDER BY id_attach_max DESC 
LIMIT 2