В чем причина полного внешнего соединения, приводящего к большему количеству строк, чем в любом родительском наборе данных? - PullRequest
0 голосов
/ 23 февраля 2020

Я работаю с двумя наборами данных, которые пытаюсь объединить с помощью команды объединения (а не объединения).

Не думаю, что я понимаю основы объединения. Я использовал полное внешнее соединение следующим образом:

    Select
      Table1.col1,
      Table1.col2, 
      Table1.date1,
      Table2.col1,
      Table2.col2,
      Table2.date2
   From Table1 full outer join 
        Table2 On Table1.date1 = Table2.date2

В итоговом комбинированном наборе данных общее количество строк было больше, чем сумма строк в таблицах Table1 и Table2.

Я пытаюсь понять, почему это произошло.

У меня сложилось впечатление, что (# строк в CombinedTable) = (# строк в Table1) + (# строк в Table2).

Почему это происходит? Как я могу это исправить?

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

Вы получите N примеров и диаграмм, вы должны иметь некоторое представление о соединениях, прежде чем просматривать эти примеры и диаграммы. Я предполагаю, что вы используете MS Sql.

Полное внешнее объединение возвращает a результирующий набор, который включает строки из левой и правой таблиц, поэтому, если у вас есть 3 строки в первой таблице и 5 строк во второй таблице, это не обязательно должно быть только 8 строк. Это также зависит от того, как значение внешнего ключа используется между этими двумя таблицами.

, если значение из второй таблицы не сопоставлено со значениями столбца первой таблицы, то эти значения возвращаются как нулевые.

как упомянутый @Caius Jard, возвращаемые значения увеличиваются в зависимости от отображенного значения. Надеюсь, это вам немного поможет.

PS Полное соединение и полное внешнее соединение одинаковы!

1 голос
/ 23 февраля 2020

Проверьте это:

TblJob
Name, Surname, Job
John, White, Developer
John, Black, Tester
John, Grey, Manager

TblDrinksPref
Name, Surname, Drink
John, White, Coffee
John, Black, Tea
John, Grey, Orange Juice

SELECT * FROM tbljob j JOIN tbldrinkspref p ON j.name = p.name

John, White, Developer, John, White, Coffee
John, White, Developer, John, Black, Tea
John, White, Developer, John, Grey, Orange Juice
John, Black, Tester, John, White, Coffee
John, Black, Tester, John, Black, Tea
John, Black, Tester, John, Grey, Orange Juice
John, Grey, Manager, John, White, Coffee
John, Grey, Manager, John, Black, Tea
John, Grey, Manager, John, Grey, Orange Juice

Объединив только имя, каждая строка в каждой таблице совпадает с другой. 3 строки в каждой таблице приводят к выводу таблиц 3х3; больше, чем сумма строк. Большинство строк, которые вы получите из объединения, - это умножение количества строк, входящих в соединение. Мы называем это декартовым продуктом, и это обычно указывает на ошибку в ваших SQL соединениях. Это может сделать любое объединение, а не только внешние. Существует объединение (называемое CROSS JOIN), единственной целью которого является создание вывода, представляющего собой идеальный декартовой продукт, потому что иногда мы действительно хотим это сделать, но в основном это указывает на проблему

Что вы можете с этим поделать ? Не объединяйте строки в несвязанные строки, делая ваши условия объединения лучше / точнее:

SELECT * 
FROM tbljob j JOIN tbldrinkspref p 
ON j.name = p.name 
  --the last name is vital to associate rows correctly in this case
  AND j.surname = p.surname

Если вы написали большой SQL и неожиданно дублировали некоторые строки, это означает, что один из ваши соединения неисправны. Закомментируйте их все обратно только к первой таблице и закомментируйте блок выбора, затем продолжайте повторный запуск sql при добавлении объединений обратно. Когда вы видите неожиданное увеличение количества строк, возможно, это сбой, но помните, что объединение может вызвать строки тоже исчезают, и вы можете оказаться в ситуации, когда добавление объединения может привести к тому, что половина строк исчезнет, ​​потому что они не соответствуют предикату соединения, а другая половина строк удвоится, потому что соединение ошибочно. Вы должны иметь в виду данные, к которым вы присоединяетесь, при оценке того, как должно измениться количество строк в результате добавления таблицы, в отличие от того, как она действительно изменяется

0 голосов
/ 23 февраля 2020

Рассмотрим две таблицы A с m строками и B с n строками и запросом, подобным этому:

select count(*)
from a full join
     b
     on <some condition>;

Эта строка может возвращать (почти) любое число от greatest(n, m) до n * m.

Возвращается greatest(n, m), если условие всегда 1: 1 (например, для идентификаторов).

Возвращается n + m, если условие всегда оценивается как ЛОЖЬ.

Возвращается n * m, если условие всегда оценивается как ИСТИНА.

Может возвращать практически любое промежуточное число, за некоторыми исключениями (например, во многих случаях было бы трудно получить n * m - 1 строк).

В отличие от этого INNER JOIN может возвращаться между 0 и n * m строками.

С другой стороны, UNION ALL всегда возвращает точно сумма строк в двух таблицах, поэтому вы можете путать UNION ALL и FULL JOIN.

...