【问题标题】:query not working need orderby before groupby?在groupby之前查询不工作需要orderby?
【发布时间】:2014-10-21 20:16:30
【问题描述】:

这应该是发布了新附件的主题列表。

此查询中的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

(编辑。)

假设我们有 3 个 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

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

【问题讨论】:

  • 在 mysql 或 sql 上工作?
  • 嘿 Johnson Jason,我介绍了一个,相当长的,猜测我的编辑(SMF 是简单论坛机器的那个),请您验证一下(否则看看什么我对你的帖子做了)?如有必要,请随意编辑/回滚。
  • 无论如何,这似乎是一个典型的每组最大 N 问题,我添加了相应的标签来对您的问题进行分类。你可以看看other questions tagged mysql+greatest-n-per-group,你可能会在其中找到你的解决方案。
  • 是的,这是 MySQL 标签下最常见的问题,但如果您想要一个特定于您需求的答案,请提供适当的 DDL 和所需的结果
  • 谁能帮我找到我的问题的具体答案?感谢 Hiral 编辑我的帖子。现在看起来好多了。仍然需要帮助。

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


【解决方案1】:

如果只有这 3 列,您需要每个主题的最近记录

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

您可以使用SUBSTRING_INDEX 的技巧而不是GROUP_CONCAT 的结果来获得id_attach 排序的主题的最新id_thumb 您可以将id_thumb 的表达式写为

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

  • GROUP_CONCAT(expr)

这会将所有id_thumbs 分组为一个主题,并为您提供 列表以双精度 || 分隔或者您可以根据需要更改分隔符 您在上面的需求我已经使用 || 来表示上面的结果 函数将类似于 thumb1||thumb2||thumb3||thumb4 这将是 由id_attach 以降序排列。

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


  • SUBSTRING_INDEX(str,delim,count)

来自 docs 从字符串 str 返回 count 之前的子字符串 分隔符 delim 的出现次数。如果计数是正数,一切 最后一个分隔符的左边(从左边算起)是 回来。如果 count 为负数,则在 final 右侧的所有内容 返回分隔符(从右数)。 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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 2015-02-01
    • 2023-02-05
    • 2016-12-27
    • 2013-10-02
    • 2018-06-26
    • 1970-01-01
    相关资源
    最近更新 更多