【问题标题】:Help with this JOIN帮助这个 JOIN
【发布时间】:2009-08-07 17:40:35
【问题描述】:
$threads = mysql_query("SELECT DISTINCT t.id, t.title
                        FROM threads t LEFT JOIN comments c ON t.id = c.parentID
                        ORDER BY c.date DESC");

while ($thread = mysql_fetch_assoc($threads)) {

 echo "<li><a href=\"?threadID=$thread[id]\">".htmlspecialchars($thread['title'])."</a></li>\n";

}

任何人都可以在此代码中看到问题吗?它不会像我想要的那样工作。我希望它是在最上面评论的线程,以及下一个最新的等。

echo $thread[parentID] 不回显

cmets:
id、评论、parentID、日期

【问题讨论】:

  • 线程肯定有项目?我通常也会做完整的 LEFT OUTER JOIN
  • 是的,我有一堆线程和 cmets
  • @OP:你能澄清一下“它不能按我想要的那样工作”部分吗?
  • 再看埃里克,我的英语不太好,但我希望你能理解
  • 如果您的某些线程没有 cmets(顺便说一句,LEFT JOIN 和 LEFT OUTER JOIN 在此 SELECT 语句中具有完全相同的效果),您 cmets.date 将为 NULL 并且由于 DESC 排序顺序这些线程将永远是 LAST。

标签: php sql mysql join


【解决方案1】:

您按不在DISTINCT 列表中的列排序。

这是MySQL 中的有效语法,但是这个ORDER BY 没有意义。

此语法为MySQL extension,此查询在四大引擎中的任何其他RDBMS 引擎中都将失败。

当SELECT或ORDER BY中的column的相同值始终对应GROUP BY或DISTINCT中的相同列值时,用于简化DISTINCT和GROUP BY查询.

如果您的情况,您可以为t.id 的每个值设置多个c.date 值,而ORDER BY 将选择哪个c.date 值远不能保证(它可以是最后一个值,第一个值或任何其他值)。

将您的查询重写为:

SELECT  t.id, t.title,
        (
        SELECT  c.date
        FROM    comments c
        WHERE   c.parent_id = t.id
        ORDER BY
                c.date DESC
        LIMIT 1
        ) lastcomment
FROM    threads t
ORDER BY
        ISNULL(lastcomment), lastcomment

【讨论】:

  • 不能让这个工作。 #1064 - ...在第 5 行的“ON c.parentID = t.id ORDER BY c.date DESC”附近使用
  • @Pryztojny:已修复。如果您发布表定义,检查语法会更容易。
  • @Quassnoi - 你为什么说不在选择列表中的列上的 ORDER BY 没有意义?它在 MySQL 5.0 中对我来说似乎工作得很好。您能否提供描述此行为的文档的链接?
  • @Quassnoi - 谢谢,但我非常清楚这不是标准 SQL。但是,这个问题是针对 MySQL 的,您的解决方案在 MySQL 中有效的原因不是因为子选择,而是因为您首先按 ISNULL() 排序:-) 也就是说,它确实有效,它也应该适用于所有符合 ANSI 的数据库,所以 +1。
【解决方案2】:

尝试在 MySQL Query 浏览器中对您的数据运行查询,看看是否返回任何结果。如果是这样,那么问题在于您的回声,而不是您的查询。

【讨论】:

  • 它确实返回了,但它不会像我想要的那样订购,最后评论的线程在顶部
【解决方案3】:

我有一段时间没有使用 MySQL,所以我知道这在 tSQL 中有效。你可以试试:

SELECT DISTINCT t.id, t.title
FROM threads t LEFT JOIN comments c ON t.id = c.parentID AND 
c.id = (SELECT MAX(c.id) FROM comments where comments.parentID = t.id)
ORDER BY c.date DESC

如果 cmets 中有很多行,这很容易变得有点慢。如果您发现性能问题,如果可以的话,将最后评论日期存储在线程中可能是有意义的。

【讨论】:

    【解决方案4】:

    我试过了,它就像你想要的那样工作

    SELECT DISTINCT t.id, t.title FROM threads AS t LEFT JOIN comments AS c ON t.id = c.parent_id ORDER BY c.date DESC
    

    我唯一改变的是使用

    来自线程AS T

    【讨论】:

      【解决方案5】:

      我不确定你想要达到什么目的,但如果你想回显 parentID,你需要将它包含在查询中。

      $threads = mysql_query("SELECT DISTINCT t.id, t.title, c.parentID
                              FROM threads t LEFT JOIN comments c ON t.id = c.parentID
                              ORDER BY c.date DESC");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-27
        • 1970-01-01
        • 2011-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多