Ошибка при выполнении оператора T-SQL UNION. Любое объяснение? - PullRequest
2 голосов
/ 25 октября 2019

При выполнении оператора T-SQL UNION в SQL Server я получаю следующую ошибку:

Сообщение 156, уровень 15, состояние 1, сервер WIN-ILO9GLLB9J0, строка 7
Неверный синтаксис рядом с ключевым словом 'UNION'

Я студент, практикующий SQL-запросы. Я должен найти название города с максимальным количеством символов и название города с минимальным количеством символов из таблицы. Если есть города с одинаковой длиной символов, я должен напечатать первый город в алфавитном порядке. Я написал следующий код:

SELECT TOP 1 CITY, LEN(CITY) 
FROM STATION 
ORDER BY LEN(CITY), CITY

UNION

SELECT TOP 1 CITY, LEN(CITY) 
FROM STATION 
ORDER BY LEN(CITY) DESC, CITY

Два запроса отлично работают самостоятельно.

Ответы [ 4 ]

3 голосов
/ 25 октября 2019

Вот один из способов заставить ваш текущий синтаксис top-union работать, используя подзапрос:

SELECT CITY, CITY_LEN
FROM
(
    SELECT TOP 1 CITY, LEN(CITY) AS CITY_LEN FROM STATION ORDER BY LEN(CITY), CITY
    UNION
    SELECT TOP 1 CITY, LEN(CITY) FROM STATION ORDER BY LEN(CITY) DESC, CITY
) t;

Однако мы могли бы так же легко использовать ROW_NUMBER здесь:

WITH cte AS (
    SELECT CITY, LEN(CITY) AS LEN_CITY,
        ROW_NUMBER() OVER (ORDER BY LEN(CITY), CITY) rn1,
        ROW_NUMBER() OVER (ORDER BY LEN(CITY) DESC, CITY) rn2
    FROM STATION
)

SELECT CITY, LEN_CITY
FROM cte
WHERE 1 IN (rn1, rn2);

Демо

1 голос
/ 25 октября 2019

Это может быть более ясный способ решения проблемы:

select * 
from station 
where len(city) in (
  select max(len(city)) from station
  union
  select min(len(city)) from station
)
order by len(city), city

Вы можете иметь заказ в подзапросе, если этот запрос использует top, но вы не можете иметь шаблон:

select * from x order by a
union 
select * from y order by a

Хотя вам разрешено:

select * from x
union 
select * from y 
order by a

Порядок в этом случае выполняется после объединения и упорядочивает весь объединенный набор, как если бы это было:

select * from (
  select * from x
  union 
  select * from y 
) z
order by a

Нет концепции сделать первый выбор из x, упорядочить его, сделать выбор из y, упорядочить его, затем объединить два набора упорядоченных результатов вместе, если вы специально не используете скобки, чтобы превратить их в субзапросы (и даже тогда, только если они используют TOP) согласно некоторым другим ответам. Как представлено в форме "x union y", в конце SQL должен быть только один порядок по заявке, и он применяется ко всему набору. Причина, по которой сервер sql суетится по этому поводу «не может иметь порядок в середине оператора» (оракул не), заключается в том, что порядок строк, выходящих из операции [union], не гарантирован, поэтому он не 'Заказывать их по пути не имеет смысла - это пустая трата времени и ресурсов. Общее правило: «если вы хотите, чтобы ваши строки были в определенном порядке, это должно быть последним, что вы делаете», и, следовательно, любые промежуточные этапы упорядочения являются пустой тратой. Вы могли бы утверждать, что этот вариант использования должен быть разрешен, и я бы нашел его действительным аргументом, равным образом допустимым, как, скажем, "top без order by не должен быть разрешен, пока он есть"Если вы покопаетесь в ней / спросите команду sql в ms, вы, вероятно, обнаружите, что работа по синтаксическому анализу sql достаточно сложна, и они остановились на «нет порядка в середине инструкции», не добавив еще одно правило «, если это неверхняя операция "

0 голосов
/ 25 октября 2019

Это должно работать:

SELECT * FROM (select TOP 1 ... here)  AS q1
UNION ALL
SELECT * FROM (select TOP 1 ... here) AS q2

Это todo с top 1 ... order by и UNION, я полагаю, очевидно.

0 голосов
/ 25 октября 2019

Есть хороший ответ с помощью функции windows, но, поскольку вы новичок, вы можете использовать подзапрос к UNION, изначально ошибка заключается в том, что вы не можете указать явный ORDER BY при попытке объединения, но с помощью подзапроса вы можете преодолетьэто.

SELECT * 
FROM
    (SELECT TOP 1 CITY, LEN(CITY) LEN 
     FROM STATION 
     ORDER BY LEN(CITY), CITY) a

UNION

SELECT * 
FROM
    (SELECT TOP 1 CITY, LEN(CITY) LEN 
     FROM STATION 
     ORDER BY LEN(CITY) DESC, CITY) a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...