Intereting Posts
В чем разница между перестройкой индекса в ONLINE и SQL Server? Уменьшение количества запросов для внутреннего соединения при присоединении базы к одной таблице Операция сопоставления MySQL с проблемой LIKE Когда Query возвращает Null на Android? Просмотр SQL для ознакомления с таблицей Могу ли я передать список хранимой процедуре? Как скопировать строку в ту же таблицу с помощью SQL Server 2008 Как сохранить результаты запросов MySQL в другой таблице? Параметрическая строка «UPDATE» работает без ошибок, но ничего не делает Должны ли мы использовать префиксы в наших соглашениях об именах таблиц базы данных? Конкретный приведение недействительно, в то время как получение scope_identity Oracle 11g – Как оптимизировать медленную параллельную вставку? Есть ли у DB2 инструкция «вставить или обновить»? Предоставить разрешение SELECT для представления, но не для базовых объектов Группировка и подсчет строк по значению до тех пор, пока он не изменится

Как выбрать строки без соответствующей записи в другой таблице?

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

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

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

Может кто-нибудь объяснить мне, как построить запрос, который возвращает все строки без совпадений в другой таблице, и что он делает, чтобы я мог самостоятельно выполнять эти запросы, а не прибегать к SO для каждой таблицы в этом беспорядке , который нет ограничений FK?

Вот простой запрос:

SELECT t1.ID FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.ID = t2.ID WHERE t2.ID IS NULL 

Ключевыми моментами являются:

  1. Используется LEFT JOIN ; это вернет ВСЕ строки из Table1 , независимо от того, есть ли соответствующая строка в Table2 .

  2. Предложение WHERE t2.ID IS NULL ; это ограничит результаты, возвращаемые только тем строкам, где идентификатор, возвращаемый из Table2 является нулевым – другими словами, в Table1 для этого конкретного идентификатора из Table1 нет записи NO . Table2.ID будет возвращен как NULL для всех записей из Table1 где идентификатор не сопоставляется в Table1 .

Я бы использовал EXISTS выражение, так как оно более мощное, вы можете точнее выбрать строки, которые хотите присоединиться, в случае LEFT JOIN вам нужно взять все, что находится в объединенной таблице. Его эффективность, вероятно, такая же, как в случае LEFT JOIN с нулевым тестом.

 SELECT t1.ID FROM Table1 t1 WHERE NOT EXISTS (SELECT t2.ID FROM Table2 t2 WHERE t1.ID = t2.ID) 

Где T2 – таблица, к которой вы добавляете ограничение:

 SELECT * FROM T2 WHERE constrain_field NOT IN ( SELECT DISTINCT t.constrain_field FROM T2 INNER JOIN T1 t USING ( constrain_field ) ) 

И удалите результаты.

 SELECT id FROM table1 WHERE foreign_key_id_column NOT IN (SELECT id FROM table2) 

В таблице 1 есть столбец, в который вы хотите добавить ограничение внешнего ключа, но значения в foreign_key_id_column не совпадают с идентификатором в таблице 2.

  1. Первоначальный выбор отображает идентификаторы из таблицы 1. это будут строки, которые мы хотим удалить.
  2. Предложение «не в» в выражении where ограничивает запрос только строками, где значение в foreign_key_id_column отсутствует в списке идентификаторов таблицы 2.
  3. Оператор select в скобках получит список всех идентификаторов, указанных в таблице 2.