PostgreSQL: как отсортировать объединенный запрос по не включенному столбцу? - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь 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 -пункта все работает нормально.И это прекрасно работает, когда я включаю столбцы, которые я хочу упорядочить по:

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, чем включать больше столбцов?

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Это правильный способ сделать это;если вам нужен только вывод id, просто оберните существующий запрос select id from (...)_.

. Причина, по которой вам нужно включить столбцы, которые вы хотите отсортировать в выборках объединения, заключается в том, что на the docs :

select_statement - это любой оператор SELECT без предложения ORDER BY, LIMIT, FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE или FOR KEY SHARE.(ORDER BY и LIMIT могут быть присоединены к подвыражению, если оно заключено в круглые скобки. Без скобок эти пункты будут приняты для применения к результату UNION , а не к его правому входному выражению.)

Таким образом, ORDER BY применяется только к результату объединения, которое, когда выводится только идентификатор книги, имеет только этот столбец.Так что да, чтобы оба набора результатов были отсортированы по этим другим столбцам, они должны быть в списках столбцов SELECT с обеих сторон UNION.

0 голосов
/ 16 октября 2018

Как насчет полного избавления от 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
0 голосов
/ 16 октября 2018

Это потому, что сначала создается результат UNION, затем выполняется ORDER BY.title и т. Д. Больше не доступны для ссылок из результата 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
...