Как сделать полное внешнее соединение, не имея полного внешнего соединения - PullRequest
4 голосов
/ 19 января 2010

На прошлой неделе я с удивлением обнаружил, что sybase 12 не поддерживает полные внешние соединения. Но мне пришло в голову, что полное внешнее объединение должно быть таким же, как левое внешнее объединение, объединенное с правым внешним объединением того же sql. Кто-нибудь может придумать причину, по которой это не будет справедливо?

Ответы [ 4 ]

1 голос
/ 19 января 2010

Если вы объедините их с UNION ALL, вы получите дубликаты. Если вы просто используете UNION без ALL, он отфильтрует дубликаты и, следовательно, будет эквивалентен полному объединению, но запрос также будет намного дороже, поскольку он должен выполнять отдельную сортировку.

1 голос
/ 10 января 2011

UNION ALL левое соединение с правым соединением, но ограничивают правое соединение только строками, которых нет в базовой таблице (возвращать нуль в соединении, если они не были бы нулевыми в таблице, если они существовали)

Для этого кода вам нужно создать две таблицы t1 и t2. t1 должен иметь один столбец с именем c1 с пятью строками, содержащими значения 1-5. t2 также должен иметь столбец c1 с пятью строками, содержащими значения 2-6.

Полное внешнее присоединение:

select * from t1 full outer join t2 on t1.c1=t2.c1 order by 1, 2;

Эквивалент полного внешнего соединения:

select t1.c1, t2.c1 from t1 left join  t2 on t1.c1=t2.c1
union all
select t1.c1, t2.c1 from t1 right join t2 on t1.c1=t2.c1 
where t1.c1 is null
order by 1, 2;

Обратите внимание на предложение where в правом соединении select, которое ограничивает результаты только теми, которые не будут дубликатами.

1 голос
/ 19 января 2010

UNION -в двух OUTER JOIN операторах должно получиться дублирование строк, представляющих данные, которые вы получите от INNER JOIN. Возможно, вам придется сделать SELECT DISTINCT для набора данных, созданного UNION. Обычно, если вам нужно использовать SELECT DISTINCT, это означает, что это не очень хорошо продуманный запрос (или я так слышал).

0 голосов
/ 19 января 2011
  1. Ну, во-первых, я не знаю, почему вы используете 12.x. Это было EndOfLifed 31 декабря 2009 года, после получения уведомления 3 апреля 2007 года. 15.0.2 (первая солидная версия) вышла в январе 2009 года. 15.5 намного лучше и была доступна 02 декабря 2009 года, так что вы два основных релиза, срок действия которых не менее 13 месяцев, устарел.

  2. ASE 12.5.4 имеет новый синтаксис соединения. (вы не указали, вы можете быть на 12.5.0.3, выпуск до этого).

  3. DB2 и Sybase не внедрили FULL OUTER JOIN по той причине, которую вы указали: она покрыта LEFT ... UNION ... RIGHT без ALL. Это не случай "не поддержки" FOJ; это случай, когда ключевое слово отсутствует.

  4. И затем возникает проблема, заключающаяся в том, что типы Sybase и DB2, как правило, никогда не будут использовать внешние объединения, не говоря уже о FOJ, поскольку их базы данных более нормализованы и т. Д.

  5. Наконец, есть совершенно обычный SQL, который вы можете использовать в любой версии Sybase, которая будет обеспечивать функцию FOJ и будет значительно быстрее в 12.x; только незначительно быстрее на 15.х. Это похоже на функцию RANK (): совершенно не нужно, если вы можете написать подзапрос.

  6. Вторая причина, по которой он не нуждается в FULL OUTER, как это делают некоторые низкоуровневые механизмы, заключается в том, что новый оптимизатор работает очень быстро, а запрос полностью нормализован. То есть. он выполняет ВЛЕВО и ВПРАВО за один проход.

  7. В зависимости от ваших несоответствий SARG и DataType и т. Д. Может потребоваться сортировка-слияние, но это также распространяется на все три уровня: подсистема дискового ввода-вывода; двигатель (двигатели); и сетевой обработчик. Если ваши таблицы секционированы, то они дополнительно распараллеливаются на этом уровне.

  8. Если ваш сервер не настроен и , ваш набор результатов очень велик, вам может потребоваться увеличить proc cache size и number of sort buffers. Вот и все.

...