kantagrawal Ответов: 2

Если мы используем оператор < gt; во внутреннем соединении. Тогда как это работает.


у нас есть 2 таблицы: TblState, TblCity. Таблица TblState имеет StateID, столбец состояния. Таблица TblCity имеет столбец StateID, CityID, City. Теперь мой вопрос таков:

Я хочу получить те государства, которые не используются в TblCity использование соединений.

Что я уже пробовал:

Выберите TblState.StateID, TblState.Состояние из TblState, где TblState.StateID NOT IN (выберите StateID из TblCity)

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

Выберите TblState.StateID, TblState.Государство от TblState внутреннее соединение TblCity на TblState.StateID <> TblCity.StateID

Richard Deeming

Визуальное представление SQL-соединений[^]

Ваш INNER JOIN код приведет к результату, который соединит каждый штат с каждым городом, который не находится в этом штате, что, очевидно, не то, что вы хотите.

2 Ответов

Рейтинг:
2

OriginalGriff

Используйте левое внешнее соединение или левое соединение и проверьте наличие нулей - это те строки, которые вам нужны.
В SQL левое соединение против левого внешнего соединения | примеры[^] но вам, вероятно, было бы лучше с исключением вместо этого: Кроме и пересекаются (Transact-SQL) - SQL Server | Microsoft Docs[^]


Рейтинг:
13

MadMyche

Если он работает нормально, почему вы хотите его изменить?
Это один из тех случаев, когда лучше оставить его в покое, так как версия LEFT JOIN этого пакета примерно на 4% медленнее, чем версия NOT IN, которую вы используете в данный момент.

Я установил некоторые #Температура таблицы для этого протестировали эти две головы-2 головы, и рассмотрели фактические планы выполнения, чтобы обнаружить, что сравнение составляет 49/51 в пользу первого утверждения

SELECT StateID, [Name]
FROM   #tblState
WHERE  StateID NOT IN ( SELECT c.StateID FROM #tblCity c )

SELECT    s.StateID, s.[Name]
FROM      #tblState s
LEFT JOIN #tblCity  c ON s.StateID = c.StateID
WHERE     c.StateID IS NULL

Я также протестировал использование оператора EXCEPT и обнаружил, что это примерно на 50% медленнее, чем соединение или в вариантах выше него (split был 28/29/43)
SELECT s.StateID  FROM #tblState s
  EXCEPT
SELECT c.StateID  FROM #tblCity c
Обратите внимание, что это вернет только StateID, а не фактическое имя состояния. Таким образом, это должно быть либо в заявлении IN, либо присоединено. Либо это еще больше снизит производительность. Добавленные к предыдущим 3 запросам разбиения плана выполнения становятся 17-17-26-41
SELECT StateID, [Name]
FROM   #tblState
WHERE  StateID IN (
         SELECT s.StateID  FROM #tblState s
           EXCEPT
         SELECT c.StateID  FROM #tblCity c
)

Теперь они находятся на столах без первичных ключей. Я действительно добавил их, а также индекс в столбце StateID в таблице #City. Это значительно ускорило дело. Вступить в против против за исключением изменения фактических планов выполнения практически идентичны: 33/34/33.
С добавлением IN в запрос EXCEPT разделение составляет 22/22/22/34.