PostgreSQL:如何对不包含列上的联合查询进行排序?

时间:2018-10-16 17:03:16

标签: sql postgresql union postgresql-9.5

我尝试ORDER 2 UNION个查询。运行此:

SELECT b.id
  FROM book.book b 
    WHERE title ILIKE '%something%' 
UNION
SELECT b.id
  FROM book.book b
    JOIN book.book_person bp
      ON bp.bookID = b.id 
    JOIN person p 
      ON p.id = bp.personID 
    WHERE lastname ILIKE '%something%' 
    ORDER BY b.title ASC, b.year DESC, b.volume ASC

给我错误:

ERROR:  42P01: missing FROM-clause entry for table "b"
LINE 12:         ORDER BY b.title ASC, b.year DESC, b.volume ASC
                          ^
LOCATION:  errorMissingRTE, parse_relation.c:3140

没有ORDER子句,它可以正常工作。当我包含要订购的cols时,它可以正常工作:

SELECT b.id, b.title, b.year, b.volume 
  FROM book.book b 
    WHERE title ILIKE '%something%' 
UNION
SELECT b.id, b.title, b.year, b.volume 
  FROM book.book b
    JOIN book.book_person bp
      ON bp.bookID = b.id 
    JOIN person p 
      ON p.id = bp.personID 
    WHERE lastname ILIKE '%something%' 
    ORDER BY "title" ASC, "year" DESC, "volume" ASC

是否有比订购更多列更好的订购UNION查询的查询方式?

3 个答案:

答案 0 :(得分:1)

这是因为首先创建UNION结果,然后执行ORDER BYtitle结果不再提供UNION等的引用。 (基本上,UNION的绑定比ORDER BY更紧密。)

要解决这个问题,只需在第二个查询和ORDER BY语句的前面加上方括号,假设您只想订购该部分:

SELECT id
...
UNION
(SELECT id
...
ORDER BY title, etc)

如果您希望对整个查询进行排序,那么您的UNION查询将必须返回所有排序列,然后您将对此进行选择:

SELECT id
FROM (
    SELECT id, title, etc
    ...
    UNION
    SELECT id, title, etc
) x
ORDER BY title, etc

答案 1 :(得分:1)

这是正确的方法;如果只需要输出id,只需用select id from (...)_包装现有查询即可。

根据the docs,需要在联合选择中包括要排序的列的原因是:

  

select_statement是任何没有ORDER BY,LIMIT,FOR NO KEY UPDATE,FOR UPDATE,FOR SHARE或FOR KEY SHARE子句的SELECT语句。 (如果将子表达式括在括号中,则可以将ORDER BY和LIMIT附加到子表达式。如果没有括号,这些子句将应用于UNION的结果,而不应用于其右侧输入表达式)

因此ORDER BY仅适用于联合的结果,当仅输出书ID时,该结果仅具有该列。是的,要使这两个结果集按其他列进行排序,它们必须位于SELECT两侧的UNION列列表中。

答案 2 :(得分:0)

如何完全摆脱union

SELECT b.id
FROM book.book b LEFT JOIN
     book.book_person bp
     ON bp.bookID = b.id LEFT JOIN
     person p 
     ON p.id = bp.personID 
WHERE b.title ILIKE '%something%' OR p.lastname ILIKE '%something%' 
ORDER BY "title" ASC, "year" DESC, "volume" ASC