UNION и сортировка

Torque
Дата: 23.05.2012 09:45:42
Вопрос такой:

Стандарт SQL говорит о том, что если порядок сортировки (ORDER BY) явно не указан, то и не надо надеяться на то, что записи будут вытащены в "нужном" порядке.
А что если у меня есть такой запрос:
SELECT
  1
FROM
  RDB$Database
UNION
SELECT
  2
FROM
  RDB$Database

ORDER BY нигде явно не указан, но есть ли гарантия что результат всегда будет таким:
1
2
а не таким:
2
1

И как, в частности, обстоит с этим дело в Firebird (2.5.1)?
Граур Станислав
Дата: 23.05.2012 09:54:08
Что мешает добавить столбец для сортировки?
SELECT
  1, -- для сортировки
  1
FROM
  RDB$Database
UNION
SELECT
  2, -- для сортировки
  2
FROM
  RDB$Database
order by 1
Таблоид
Дата: 23.05.2012 09:54:51
Torque,

UNION без кляузы 'ALL' требует добавить из источника S, указанного "под" ним, в набор T, сформированный "выше" него, только те строки, которые отсутствуют в T.
В firebird'e наличие строк в наборе T проверяется сортировкой последнего. Это приведёт к выводу строк в УПОРЯДОЧЕННОМ виде.
SQL> create table t2(f01 int);
SQL> commit;
SQL> insert into t2 values(20000);
SQL> insert into t2 values(2);
SQL> commit;
SQL> create table t3(f01 int);
SQL> commit;
SQL> insert into t3 values(33333);
SQL> insert into t3 values(3);
SQL> commit;
SQL> select * from t2;

F01
============
20000
2

SQL> select * from t3;

F01
============
33333
3

SQL> select * from t2 union select * from t3;

F01
============
2
3
20000
33333

PS. Сортировка в плане НЕ показывается, так что затраты могут быть существенными и вроде "непонятно отчего".
Torque
Дата: 23.05.2012 10:05:48
Вопрос был чисто академическим.

Таблоид,
в общем я так понял, что полагаться на вышеуказанный порядок не стоит, т.е. надо писать что-то типа:
SELECT
  Val
FROM
  (
    SELECT
      1 Val,
      1 Pos
    FROM
      RDB$Database
    UNION
    SELECT
      2 Val,
      2 Pos
    FROM
      RDB$Database
  )
ORDER BY
  Pos
kdv
Дата: 23.05.2012 10:09:19
Torque,

кроме этого нужно еще понимать разницу между union и union all. и не мучить сервер union, там где нужен union all.
Таблоид
Дата: 23.05.2012 13:06:14
Есть интересный нюанс. NULL-значения, выводимые в столбце, при UNION DISTINCT'e также считаются только один раз, т.е. для них НЕ действует правило сопоставления NULL = NULL ? ==> UNKNOWN и NULL будет выведен только 1 раз, как и все остальные значения.
SQL> select null f from rdb$database union select null from rdb$database;

F
======
<null>

SQL>
Граур Станислав
Дата: 23.05.2012 13:13:20
Кстати

select 1 from rdb$database
union
select null from rdb$database

выводит
==
null
1
Граур Станислав
Дата: 23.05.2012 13:14:42
А

select 1 from rdb$database
union all
select null from rdb$database

===
1
null

Чудеса ))
dimitr
Дата: 23.05.2012 13:32:08
Таблоид,

оператор DISTINCT работает не по принципу равенства. NULL IS DISTINCT FROM NULL = FALSE.

Граур Станислав,

чему удивляемся? Наличию сортировки в первом случае и ее отсутствию во втором?
Граур Станислав
Дата: 23.05.2012 14:04:04
dimitr
чему удивляемся? Наличию сортировки в первом случае и ее отсутствию во втором?


Я удивляюсь, как быстро нашлись два примера, которые имхо наглядно отвечают на вопрос автора "нужно ли надеяться".

P.S.
А то, почему в первом случае так, а во втором эдак, они и так ясно.
UNION убирает дубликаты отсюда и сортировка.