Элементы ORDER BY должны появляться в списке выбора, если инструкция содержит оператор UNION, INTERSECT или EXCEPT (вариант) - PullRequest
0 голосов
/ 24 сентября 2018

Я прочитал все вопросы, которые я могу найти на SO, относящиеся к этой ошибке, и они не совсем описывают эту ситуацию.В других случаях люди делают такие вещи, как ссылки только на одну из псевдонимов таблиц (с одной стороны объединения) в следующем порядке - я понимаю, почему SQLS жалуется на все другие вопросы, которые я читал, об этой конкретной ошибке.

Я не могу понять, почему SQL Server имеет проблемы с этим order by;единственные столбцы, упомянутые в порядке, определенно являются членами набора результатов select:

--example data:
-- a,b,c
-- 1, ,2
--  ,3,5

SELECT    1 AS a, null AS b, 2 AS c INTO #tmp
UNION
SELECT null AS a,    3 AS b, 5 AS c 

--let's call it a lame version of a rollup
SELECT * FROM #tmp            --detail rows
UNION ALL
SELECT a, b, SUM(c) FROM #tmp --summary row
GROUP BY a, b

--the problem
ORDER BY COALESCE(a, b);

DROP TABLE #tmp;

Набор результатов содержит столбцы a и b, нет никакой двусмысленности, которую я могу видеть .. Даже псевдонимывсе (иначе) не помогает:

SELECT t.a AS z, t.b AS y, t.c FROM #tmp t
UNION ALL
SELECT u.a AS z, u.b AS y, SUM(c) AS c FROM #tmp u
GROUP BY u.a, u.b
ORDER BY COALESCE(z, y);

На самом деле, странно, SQL Server, похоже, жалуется еще больше:

Msg 207, Level 16, State 1, Line 6
Invalid column name 'z'.
Msg 207, Level 16, State 1, Line 6
Invalid column name 'z'.           --why complain twice?
Msg 207, Level 16, State 1, Line 6
Invalid column name 'y'.
Msg 104, Level 16, State 1, Line 6
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.

Единственная вещь, которая работает, это завернуть егов качестве другого выберите:

SELECT * FROM(
  SELECT * FROM #tmp
  UNION ALL
  SELECT a, b, SUM(c) AS c FROM #tmp
  GROUP BY u.a, u.b
) a
ORDER BY COALESCE(a, b);

SELECT * FROM(
  SELECT t.a AS z, t.b AS y, t.c FROM #tmp t
  UNION ALL
  SELECT u.a AS z, u.b AS y, SUM(c) AS c FROM #tmp u
  GROUP BY u.a, u.b
) z
ORDER BY COALESCE(z, y);

Что я думал, концептуально SQL Server делал со своим набором результатов, прежде чем он все равно обработал order by. Так что же дает?

1 Ответ

0 голосов
/ 24 сентября 2018

Согласно примечанию от HoneyBadger, кажется, что на самом деле нужно просто взять SQLS по номинальному значению сообщения об ошибке и не предполагать, что он формирует результирующий набор из запроса объединения, связанный с именами, данными столбцам в ведущем выборе, чтоЗатем упорядочивается ..

Это ...

SELECT a, b, COALESCE(a,b) FROM t
UNION ALL
SELECT a, b, COALESCE(a,b) FROM u
ORDER BY COALESCE(a,b)

... работает, предположительно, потому что оно непосредственно указывает COALESCE(a,b) в списке выбора, а также ORDER BY

Это ...

SELECT * FROM(
  SELECT a, b FROM t
  UNION ALL
  SELECT a, b FROM u
)z
ORDER BY COALESCE(a,b)

... работает, предположительно, потому что заказываемый запрос не содержит UNION

Интересное сочетание результатов из других БД, использующих нерабочая форма:

Oracle:

ORA-01785: элементом ORDER BY должен быть номер выражения списка SELECT

PostGres:

ОШИБКА: недопустимое предложение UNION / INTERSECT / EXCEPT ORDER BY Подробно: могут использоваться только имена столбцов результата, но не выражения или функции.Подсказка: добавьте выражение / функцию к каждому SELECT или переместите UNION в предложение FROM

MySQL:

(работает)

...