Как выполнить полное внешнее соединение, не имея полного внешнего соединения

StackOverflow https://stackoverflow.com/questions/2089658

  •  21-09-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

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

Для этого кода вам нужно будет создать две таблицы 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 справа от объединенного выбора, которое ограничивает результаты только теми, которые не будут повторяться.

  1. Ну, во-первых, я не знаю, почему вы используете 12.x.Это было EndOfLifed 31 декабря 2009 г., после получения уведомления 3 апреля 2007 г.15.0.2 (первая полноценная версия) вышла в январе 2009 года.Версия 15.5 намного лучше и была доступна 2 декабря 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.x.Это что-то вроде функции RANK():совершенно ненужно, если вы можете написать подзапрос.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top