PostgreSQL:如何对未包含列的联合查询进行排序?
PostgreSQL: How to sort union query on not included column?
我尝试 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
ed queris?
那是因为首先创建 UNION
结果,然后执行 ORDER BY
。 title
等不再可用于 UNION
结果的引用。 (基本上 UNION 比 ORDER BY 绑定更紧密。)
因此,为了解决这个问题,只需将第二个查询和 ORDER BY 语句括起来,假设您只想订购该部分:
SELECT id
...
UNION
(SELECT id
...
ORDER BY title, etc)
如果您希望对完整查询进行排序,您的 UNION 查询将必须 return 所有排序列,然后您将对其执行 select:
SELECT id
FROM (
SELECT id, title, etc
...
UNION
SELECT id, title, etc
) x
ORDER BY title, etc
这才是正确的做法;如果您只需要 id
输出,只需用 select id from (...)_
.
包装您现有的查询
根据 the docs:
,您需要在联合选择中包含要排序的列的原因是
select_statement
is any SELECT statement without an ORDER BY, LIMIT, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE, or FOR KEY SHARE clause. (ORDER BY and LIMIT can be attached to a subexpression if it is enclosed in parentheses. Without parentheses, these clauses will be taken to apply to the result of the UNION, not to its right-hand input expression.)
因此 ORDER BY
仅适用于并集的结果,当仅输出图书 ID 时,只有该列可用。所以是的,要让两个结果集都按其他列排序,它们必须位于 UNION
.
两侧的 SELECT
列列表中
完全摆脱 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
我尝试 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
ed queris?
那是因为首先创建 UNION
结果,然后执行 ORDER BY
。 title
等不再可用于 UNION
结果的引用。 (基本上 UNION 比 ORDER BY 绑定更紧密。)
因此,为了解决这个问题,只需将第二个查询和 ORDER BY 语句括起来,假设您只想订购该部分:
SELECT id
...
UNION
(SELECT id
...
ORDER BY title, etc)
如果您希望对完整查询进行排序,您的 UNION 查询将必须 return 所有排序列,然后您将对其执行 select:
SELECT id
FROM (
SELECT id, title, etc
...
UNION
SELECT id, title, etc
) x
ORDER BY title, etc
这才是正确的做法;如果您只需要 id
输出,只需用 select id from (...)_
.
根据 the docs:
,您需要在联合选择中包含要排序的列的原因是
select_statement
is any SELECT statement without an ORDER BY, LIMIT, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE, or FOR KEY SHARE clause. (ORDER BY and LIMIT can be attached to a subexpression if it is enclosed in parentheses. Without parentheses, these clauses will be taken to apply to the result of the UNION, not to its right-hand input expression.)
因此 ORDER BY
仅适用于并集的结果,当仅输出图书 ID 时,只有该列可用。所以是的,要让两个结果集都按其他列排序,它们必须位于 UNION
.
SELECT
列列表中
完全摆脱 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