如何在MySQL join运算符中对组进行排序?

时间:2014-09-07 02:14:53

标签: mysql sql

在我的sql中,我有这个查询

SELECT * FROM threads t 
JOIN (
    SELECT c.* 
    FROM comments c 
    WHERE c.thread_id = t.id 
    ORDER BY date_sent
    ASC LIMIT 1
    ) d ON t.id = d.thread_id 
ORDER By d.date_sent DESC

基本上我有两个表,线程和注释。注释具有线程表的外键。我想为每个线程行获取earliest注释行。线程应该至少有1条评论。如果没有,则不应包括线程行。

在我上面的查询中,我在线程上做了一个select,然后我用自定义查询加入它。我想使用t.id,其中t是括号外的选择表。在括号内,我创建了一个新的结果集,其注释用于当前线程。我在那里进行排序和限制。

然后,我再次对它进行排序,因此它最早在顶部。但是,当我运行它时,它会给出错误#1054 - Unknown column 't.id' in 'where clause'

有谁知道这里有什么不对吗?

由于

2 个答案:

答案 0 :(得分:1)

unknown column t.id是因为别名t在子查询中是未知的,但实际上不需要它,因为你在ON子句中加入了它。 / p>

使用在子查询中按LIMIT 1分组的MIN(date_sent)聚合,而不是thread_id。如果两个表中的列具有相同的名称,请在连接查询中使用SELECT *时要小心;最好明确列出列。

SELECT
  /* List the columns you explicitly need here rather than *
     if there is any name overlap (like `id` for example) */
  t.*,
  c.*
FROM
  threads t
  /* join threads against the subquery returning only thread_id and earliest date_sent */
  INNER JOIN (
    SELECT thread_id, MIN(date_sent) AS firstdate
    FROM comments
    GROUP BY thread_id
  ) earliest ON t.id = earliest.thread_id
  /* then join the subquery back against the full comments table to get the other columns 
     in that table. The join is done on both thread_id and the date_sent timestamp */
  INNER JOIN comments c 
    ON earliest.thread_id = c.thread_id
    AND earliest.firstdate = c.date_sent
ORDER BY c.date_sent DESC

答案 1 :(得分:1)

迈克尔的回答是正确的。这是另一个答案,它遵循更多的查询形式。您可以作为相关子查询执行所需操作,然后加入其他信息:

SELECT *
FROM (SELECT t.*,
             (SELECT c.id
              FROM comments c 
              WHERE c.thread_id = t.id 
              ORDER BY c.date_sent ASC
              LIMIT 1
             ) as mostrecentcommentid
      FROM threads t 
     ) t JOIN
     comments c
     on t.mostrecentcommentid = c.id
ORDER By c.date_sent DESC;

这可能会有更好的性能,因为它不需要聚合所有数据。但是,为了提高性能,您需要comments(thread_id, date_set, id)上的索引。