【问题标题】:SQL include entries of join table that don't exist?SQL包含不存在的连接表条目?
【发布时间】:2012-09-10 22:37:02
【问题描述】:

我有一个objects 表和votes 表。我目前正在对它们进行分组并按最近的投票排序:

SELECT objects.id, objects.name, MAX(votes.created_at) AS mv 
       FROM "objects"
       INNER JOIN "votes" ON "votes"."object_id" = "objects"."id" 
       GROUP BY objects.id, objects.name 
       ORDER BY mv DESC

但是,这只返回有投票的对象。我搜索了 SO 并找到了有关如何包含不存在的结果的答案,但我希望同时包含那些存在和不存在的结果。

有没有办法将上述所有没有投票的对象都添加到末尾?

【问题讨论】:

    标签: sql postgresql null sql-order-by left-join


    【解决方案1】:

    使用LEFT JOIN,在找不到匹配行的地方填充NULL 值 - 如you found out yourself

    超级令人沮丧,因为它完美运行,除了所有 没有投票的条目在开头!

    现在,NULL 通常排在最后。但与DESC 相反,它是first。在 Postgres 中,您可以使用 NULLS LASTNULL 显式排序到最后(从 8.3 版开始):

    
    SELECT o.id, o.name, max(v.created_at) AS lastest_vote
    FROM   objects o
    LEFT   JOIN votes v ON v.object_id = o.id 
    GROUP  BY o.id, o.name
    ORDER  BY lastest_vote DESC NULLS LAST, o.name; -- name only as tiebreaker

    如果objects.id 是主键,您可以简化GROUP BY(在 Postgres 9.1 或更高版本中):

    GROUP  BY o.id -- primary key covers all columns of this table
    

    【讨论】:

      【解决方案2】:

      INNER JOIN 基本上返回在两个表上都有记录的结果。然后你应该使用LEFT JOIN,因为它会返回从左边开始的所有行,无论它在右表上是否有匹配的记录。

         SELECT objects.id, objects.name, MAX(votes.created_at) AS mv 
         FROM "objects"
                LEFT JOIN "votes" ON "votes"."object_id" = "objects"."id" 
         GROUP BY objects.id, objects.name 
         ORDER BY mv DESC
      

      Visual Representation of JOINs

      希望这会有所帮助。

      【讨论】:

      • 它有效,但是所有没有投票的对象都显示在有投票的对象之上。我怎样才能把没有投票的人放在下面?
      • @Marc 将此语法用于ORDER BY COALESCE(MAX(votes.created_at), -1) DESC
      • 嗯。它给了我这个错误:“COALESCE 类型时间戳没有时区和整数无法匹配”
      • @Marc 哦,这可能会起作用ORDER BY COALESCE("votes"."object_id", -1) DESC,因为在这种情况下"votes"."object_id" 可能为空。
      • 仅按 ID 对所有条目进行排序,而不是对存在的条目进行最近的投票
      【解决方案3】:

      在您的声明中使用"LEFT OUTER JOIN" 而不是"INNER JOIN"

      干杯

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-12
        • 2014-11-17
        • 2014-12-30
        • 1970-01-01
        • 2013-06-27
        相关资源
        最近更新 更多