Удалить из таблицы B, где значение столбца похоже на таблицу a с подстановочными знаками

#mysql #sql #subquery #left-join #sql-delete

#mysql #sql #подзапрос #левое соединение #sql-удалить

Вопрос:

Итак, у меня есть две таблицы

 seeds
- id
- domain

subdomain
- id 
- domain
- ip
  

Я хочу отфильтровать поддомены по доменам

например

 seeds
Id  Domain
0   google.com
1   test.com

subdomain
Id   domain          ip
0    test.google.com    null
1    api.google.com     null
2    dnr.com            null
3    neverssl.com       null
  

Я пытаюсь написать один запрос, который удаляет строки в, subdomain которые не содержат domain из seeds

Что вы пробовали?

 delete subdomain 
where id not in 
(select subs.id from seed as seeds 
join 
subdomain as subs on subs.domain 
like concat('%', seeds.domain));
  

и

 delete subdomain 
where id not in
(SELECT sd.id
FROM subdomain sd
LEFT JOIN seed s
  ON sd.domain LIKE CONCAT('%', s.Domain)
WHERE s.id IS NULL)
  

оба этих запроса просто удаляют все строки

Комментарии:

1. Так не должно ли это быть subs.subdomain вместо subs.domain ?

2. Обе реальные таблицы имеют идентификатор, домен в качестве своих столбцов, я пытался сделать это более понятным для вопроса, поэтому я изменил таблицу b на поддомен

3. Извините, это не делает его более понятным, если запрос не соответствует образцу данных.

Ответ №1:

Вы можете использовать not exists :

 delete from subdomain
where not exists (
    select 1
    from seeds s
    where subdomain.domain like concat('%', s.domain)
)
  

ДЕМОНСТРАЦИЯ

Комментарии:

1. это удалило все строки

2. (Я могу восстановить его, просто хотел сообщить вам, что это не сработало, лол)

3. @AnthonyRussell: Я только что обновил запрос, чтобы соответствовать новым именам таблиц, поскольку вы изменили их в вопросе. Это может сделать то, что вы хотите.

4. да, я учел измененные имена таблиц. Я не уверен, почему это не работает

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

Ответ №2:

Используйте шаблон LEFT JOIN NULL , чтобы найти строки, которые не совпадают.

 DELETE d
FROM subdomain AS d
LEFT JOIN seeds AS s ON d.domain LIKE CONCAT('%', s.domain)
WHERE s.id IS NULL
  

ДЕМОНСТРАЦИЯ