Как я могу упорядочить записи в UNION без ORDER BY?

Как я могу быть уверен, что в моем наборе результатов будет a первым и b вторым? Это помогло бы мне решить сложную проблему с заказом.

Вот упрощенный пример того, что я делаю:

SELECT a FROM A LIMIT 1 
UNION 
SELECT b FROM B LIMIT 1;

person markus    schedule 04.03.2009    source источник
comment
@tharkun: я понимаю, что вам не нравится RichB, но понимаю, как выглядит ваш вопрос на главной странице, если вы видите только две строки, это код SQL, а не вопрос. Вот почему он отредактировал его так, как он это сделал, и, честно говоря, его редактирование сделало вопрос намного лучше.   -  person George Stocker    schedule 12.03.2009
comment
@tharkun: отделите его «резкий» тон от его правок. Они отдельные. Он уверен в своем языке; но это не делает его правки менее актуальными.   -  person George Stocker    schedule 12.03.2009
comment
Откатился на правки Рича. Не поддерживая никого и ничего, кроме качества вопроса.   -  person Jon B    schedule 12.03.2009
comment
@tharkun: мы ежедневно обсуждаем эту тему на irc.freenode.net #stackoverflow. Не стесняйтесь присоединиться к каналу и узнать меня (нас?)   -  person George Stocker    schedule 12.03.2009


Ответы (7)


Я не думаю, что порядок гарантирован, по крайней мере, не во всех СУБД.

То, что я сделал в прошлом, чтобы контролировать порядок в UNION:

(SELECT a, 0 AS Foo FROM A LIMIT 1)
UNION
(SELECT b, 1 AS Foo FROM B LIMIT 1)
ORDER BY Foo
person Dana    schedule 04.03.2009
comment
о, это гениально, легко и гениально! - person markus; 04.03.2009
comment
Вы уверены, что order by не будет применяться только к последнему запросу в объединении? - person Kjetil Watnedal; 04.03.2009
comment
Ах, в SQL Server ORDER BY применяется к результатам UNION, а не только ко второму подзапросу. - person Dana; 04.03.2009
comment
ORDER BY применяется ко всему UNION, а не ко второй части. Со скобками или без них и во всех 3-х СУБД: Postgres, SQL Server, MySQL. Единственный способ применить его во 2-й части — это использовать вот такие скобки: SELECT ...) UNION (SELECT ...ORDER BY); Но это не значит, что результат будет упорядочен. UNUON не обязательно сохраняет порядок внутренних подзапросов. - person ypercubeᵀᴹ; 30.09.2016

Ваш результирующий набор с UNION устранит различные значения.

Я не могу найти никаких доказательств в документации, но из 10 лет опыта я могу сказать, что UNION ALL сохраняет порядок, по крайней мере, в Oracle.

Однако не полагайтесь на это, если вы строите атомную электростанцию ​​или что-то в этом роде.

person Quassnoi    schedule 04.03.2009
comment
Кажется, это работает. Имеет смысл, что объединение испортит порядок, если оно проверяет наличие дубликатов, в то время как объединение все не будет - person David; 19.06.2017

Нет, порядок результатов в SQL-запросе определяется только предложением ORDER BY. Возможно, в какой-то ситуации вы увидите упорядоченные результаты без предложения ORDER BY, но это случайно (например, побочный эффект текущего плана запроса оптимизатора) и не гарантируется.

В чем сложность заказа?

person Tony Andrews    schedule 04.03.2009
comment
спасибо, я так и думал ... сложная проблема заказа, если она останется сложной, будет содержанием другого вопроса, который я бы связал здесь. - person markus; 04.03.2009

Я знаю, что для Oracle нет способа гарантировать, что выйдет первым без заказа. Проблема в том, что если вы попробуете это, он может получиться в правильном порядке даже в большинстве случаев, когда вы его запускаете. Но как только вы будете полагаться на него в продакшене, он выйдет неверным.

person Thomas Jones-Low    schedule 04.03.2009

Я бы подумал, что нет, поскольку базе данных, скорее всего, потребуется выполнить ORDER BY для UNION.

UNION ALL может вести себя иначе, но YMMV.

person cagcowboy    schedule 04.03.2009
comment
UNION ALL просто гарантирует, что будут возвращены все записи. Простой UNION фильтрует дубликаты. - person Dana; 04.03.2009

Короткий ответ: да, вы получите А, а затем Б.

person Bill    schedule 04.03.2009
comment
и какой длинный ответ, учитывая, что все остальные говорят обратное? - person markus; 04.03.2009
comment
Длинный ответ будет заключаться в том, что без предложения ORDER BY вы получите FIFO на основе предложения UNION. Например, таблица B, указанная первой в UNION, даст B->A. UNION сам по себе не включает никакого поведения сортировки. - person Bill; 04.03.2009
comment
люди, кажется, не согласны с вами, вы можете доказать свое утверждение? - person markus; 04.03.2009
comment
создать таблицу #A (A VARCHAR(10)) создать таблицу #B (B VARCHAR(10)) INSERT INTO #A(A) VALUES('A') INSERT INTO #A(A) VALUES('AA') INSERT INTO #A(A) VALUES('AAA') INSERT INTO #B(B) VALUES('B') INSERT INTO #B(B) VALUES('BB') INSERT INTO #B(B) VALUES('BBB') SELECT a from #A UNION SELECT b FROM #B; - person Bill; 04.03.2009
comment
вы получите: ААААААВВВВВВ - person Bill; 04.03.2009
comment
согласно другим плакатам, это не гарантируется. но все равно спасибо, что показали другую сторону медали. - person markus; 04.03.2009
comment
Я какой rdbms? При низких значениях может быть да, но не гарантируется. с очень длинной таблицей не потому, что может использоваться хэш, и весь порядок нарушается. - person FerranB; 04.03.2009
comment
БД в целом не гарантируют какой-либо порядок возвращаемых результатов, если только не запрошен определенный порядок. Наличие примера, который работает в некоторых случаях, не гарантирует, что он будет работать всегда. - person Beska; 04.03.2009

person    schedule
comment
это, кажется, профессиональная версия того, что предлагает Дана, спасибо! - person markus; 04.03.2009
comment
это если я не хочу, чтобы порядковый номер в наборе результатов, верно?! - person markus; 04.03.2009
comment
и что делает одинокая буква t в строке 7? - person markus; 04.03.2009
comment
Правильно: разница здесь в том, что он скрывает порядковый номер. «t» дает производной таблице имя — вы можете использовать все, что хотите, но, поскольку мы не используем ее где-либо еще, фактическое значение не важно. Но он не будет компилироваться без чего-то там. - person Joel Coehoorn; 04.03.2009
comment
Поскольку добавление порядкового столбца означает, что дубликатов не будет, я бы переключился на UNION ALL (я знаю, преждевременная оптимизация, но я всегда применяю ее в этой ситуации) - person Damien_The_Unbeliever; 04.03.2009