Перейти к содержимому

Sql найти записи которых нет в другой таблице

  • автор:

Как вывести из таблицы только строки, которых нет в другой таблице?

Как вывести из таблицы t1 строки, которых нет в таблице t2 ? Можно ли это сделать без подзапросов?

Отслеживать

51.6k 200 200 золотых знаков 59 59 серебряных знаков 242 242 бронзовых знака

задан 20 ноя 2020 в 8:12

1 1 1 золотой знак 1 1 серебряный знак 1 1 бронзовый знак

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Вот как звучит вопрос — вывести из таблицы t1 строки, которых нет в таблице t2, так и пишите (только по английски):

select t1.* from t1 where not exists ( select 1 from t2 where t2.id = t1.id) 

Доп. вопрос: Можно ли это сделать без подзапросов?. Можно, но вряд ли нужно, т.к. скорее никаких преимуществ это не даст:

select t1.* from t1 left join t2 on t2.id = t1.id where t2.id is null 

Как найти только те записи, ID у которых нет в другой таблице в БД?

Всем привет! Нужно достать записи с таблицы orders, id у которых нет в таблице applications(столбик order_id).
В таблице applications в столбике order_id хранятся id записей с таблицы orders.
Пробовал так, но так он сравнивает только 1 запись в таблице applications, а другие нет.

$get_orders = mysqli_query($db, "SELECT * FROM `orders` WHERE `city` = '$_SESSION[city]' AND `id` NOT IN (SELECT `id` FROM `applications` WHERE `driver` = '$_SESSION[id]' AND `order_id` = `orders`.`id`)");

Пробовал использовать INNER JOIN, но так все записи с orders повторяются столько раз, сколько есть записей в таблице applications.

  • Вопрос задан более трёх лет назад
  • 156 просмотров

Sql найти записи которых нет в другой таблице

переделал код из v8: Временные таблицы и индексы в запросах на «Не в» и Левое соединение . есть NULL, запустил

(10) А что не так с ЕстьNull-ом?

(16)+
Количество ~160к, отбор ~8к, повторений: 1

Отбор через массив: 1
Отбор через левое соединение: 1
Отбор через не В: 189
Отбор через не В (Exists): 1
Отбор через внутреннее соединение + индекс: 1
Отбор через не В + индекс: 1
Отбор через не В (Exists) + индекс: 1

дисквалифицировали В за унылость, увеличили повторения до 10:

Количество: 162 168 отбор: 8 108 повторений: 10
Отбор через массив: 18
Отбор через соединение: 16
Отбор через В (Exists): 17
Отбор через соединение + индекс: 16
Отбор через В + индекс: 17
Отбор через В (Exists) + индекс: 17

можно загрузить обе таблицы в одну большую,добавить числовое поле, для первой 1, для второй 2.
Потом сгруппировать с сумированием по новому полю, потом отобрать только записи, где сумма = 1 (будут только те что в 1 таблице) =2 где только во второй = 3 где в обоих.

(19) попробуй запусти через объединение, интересно сколько покажет времени.

Количество: 162 170 отбор: 8 108 повторений: 10
Отбор через массив: 18
Отбор через соединение: 16
Отбор через В (Exists): 15
Отбор через соединение + индекс: 15
Отбор через В + индекс: 17
Отбор через В (Exists) + индекс: 16
Отбор через Объединение: 27

Запрос.Текст =
»
|ВЫБРАТЬ
| ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
| &ТаблицаСсылок КАК ТаблицаСсылок
|
|ИНДЕКСИРОВАТЬ ПО
| ТаблицаСсылок.Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Вложенный.Ссылка
|ИЗ
| (ВЫБРАТЬ
| Контрагенты.Ссылка КАК Ссылка,
| 1 КАК Группировка
| ИЗ
| Справочник.Контрагенты КАК Контрагенты
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ТаблицаСсылок.Ссылка,
| -1
| ИЗ
| ТаблицаСсылок КАК ТаблицаСсылок) КАК Вложенный
|
|СГРУППИРОВАТЬ ПО
| Вложенный.Ссылка
|
|ИМЕЮЩИЕ
| СУММА(Вложенный.Группировка) = 1″;

(22) спасибо.
Чет я не догнал, получается что объединить 2 таблицы и отобрать по нулу быстрее чем «не в»?
(25) мораль в том, что нужно в каждом конкретном случае проверять отдельно разные варианты

(16) Поэксприментировал немного с планами запросов.
Есть сомнение по корректности теста на exist. Конкретное на

|ГДЕ
| (Контрагенты.Ссылка, ИСТИНА) В
| (ВЫБРАТЬ
| ТаблицаСсылок.Ссылка,
| ИСТИНА
| ИЗ
| ТаблицаСсылок)

судя по тому во что 1С транслирует такую конструкцию для скуля ( из v8: Оператор «ИЛИ», конструкция «ВЫБОР» и вероятность фуллскана при них ) там получается

AND EXISTS(SELECT
1
FROM #tt2 T2 WITH(NOLOCK)
WHERE (T1._Fld18873RRef = T2._Q_001_F_000RRef) AND (T1._Fld18875RRef = T2._Q_001_F_001RRef))

В случае если второе поле Истина, мне кажется, при трансляции его просто пропустят и останется exist по одному полю.

При этом для in и exist по одному полю строятся абсолютно одинаковые планы запроса.

Select
id
From sc72
Where id in (select id from #tempkl)

Select
id
From sc72 as sc
Where exists (select id from #tempkl where )

а вот для exsist по двум полям уже другой план c hash match

Select
id
From sc72 as sc
Where exists (select id from #tempkl where and sp81=sc.sp81)

(27) за планы не смотрел, а факт в том, что В по одному полю транслируется в in, а по 2м и более — в exists (по крайней мере для mssql)

(28) Согласен, но меня смущает именно второе поле Истина. Лучше бы может дернуть во временную таблицу реальное поле вместо Истина.

К тому же план для

Select
id
From sc72 as sc
Where exists (select id from #tempkl where and 1=1)

идентичен по одному полю и in.

(29) да. а вот для НЕ В — уже очень разные планы, судя по времени выполнения, которое в 200 раз различается

Для in получается Nested loops / inner join

Для not in получается Merge join / Left anti semi join

это еще зависит от соотношения количества записей в таблицах и наличия индекса.

Выбрать значения, которых нет в другой таблице

но результатов не выводится. Видимо он выполняет сначала первое условие и убирает сразу все строки.

Пример в первой таблице m=1 и r=2
Во второй таблице m=1 и r=1
то он должен вывести все строки из первой таблицы,

а вот если в первой таблице m=1 и r=2
Во второй таблице m=1 и r=2
то он ничего выводить не должен.

Немогу разобраться как это реализовать сравнение сразу по всем столбцам таблицы.

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Найти строки в таблице, которых нет в другой таблице
Здравствуйте! Помогите, пожалуйста, составить запрос. Думаю думаю, никак не могу сообразить.

Выбрать запись из таблицы, если нет записи в другой таблице
Мутновато назвал тему но по другому никак. Есть две таблици users и members. Поля такие users.

Запрос в 1С: если нет в одной таблице, выбрать из другой
Подскажите совет, а то не могу сообразить. Есть у меня пакетный запрос, который ищет цену на.

Записи, айди которых нет в другой таблице
Есть две таблицы. Допустим users (поля id, name, surname) и user_groups (uid, gid, date_joined).

4214 / 3054 / 582
Регистрация: 21.01.2011
Сообщений: 13,205

Лучший ответ

Сообщение было отмечено cybf18 как решение

Решение

ЦитатаСообщение от cybf18 Посмотреть сообщение

Немогу разобраться как это реализовать сравнение сразу по всем столбцам таблицы
Не знаю, как в MySQL, но в Oracle есть такая конструкция:

1 2 3 4 5
WHERE (fld1_1, fld1_2) NOT IN (SELECT fld2_1, fld2_2 FROM tab2 )

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *