SQL Исключить LIKE элементы из таблицы

Я пытаюсь выяснить, как исключить элементы из оператора select из таблицы A, используя список исключений из таблицы B. Уловка заключается в том, что я исключаю на основе префикса поля.

Таким образом, значение поля может быть «FORD Muffler», и чтобы исключить его из базового запроса, я бы сделал:

SELECT FieldName 
FROM TableName 
WHERE UPPER(ColumnName) NOT LIKE 'FORD%'

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

SELECT FieldName 
FROM TableName 
WHERE UPPER(ColumnName) NOT IN (Select FieldName2 FROM TableName2)

Проблема в том, что он исключает только точные совпадения, а не LIKE или подстановочные знаки (%).

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

Обновлено: Извините, я использую SQL Server (2005).

Являются ли значения в таблице 2 фиксированной длиной или переменной?

DJ. 10.01.2009 01:42

Они могут быть разной длины.

MaxGeek 10.01.2009 02:12

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

Tom H 10.01.2009 03:19
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
5
3
25 269
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Думаю, это сработает:

SELECT FieldName
FROM TableName
LEFT JOIN TableName2 ON UPPER(ColumnName) LIKE TableName2.FieldName2 + '%'
WHERE TableName2.FieldName2 IS NULL

Почему у вас WHERE TableName2.FieldName2 IS NULL? Казалось бы, это противоречит цели объединения.

recursive 10.01.2009 01:57

Это связано с тем, что ему нужны только те записи, которые НЕ имеют совпадений для соединения. Поскольку это левое внешнее соединение, записи из первой таблицы по-прежнему доступны при применении фильтра where. Записи из 2-й таблицы просто имеют нулевые значения.

Joel Coehoorn 10.01.2009 02:00

Другими словами, INNER-соединение вернет в точности противоположное тому, что он хочет: записи, в которых 1-я таблица ЕСТЬ как 2-я. ВНЕШНЕЕ соединение без предложения where вернет ОБА: записи, которые соответствуют И не совпадают. Затем добавьте это предложение where, и мы вернемся только к записям, которые НЕ совпадают.

Joel Coehoorn 10.01.2009 02:08

Не знаю, насколько это будет эффективно, но должно работать:

SELECT FieldName 
FROM TableName t1
WHERE NOT EXISTS (
    SELECT *
    FROM TableName2 t2
    WHERE t1.FieldName LIKE t2.FieldName2 + '%'
)

Я бы изменил это на «выберите 1», а не «выберите *», поскольку нет смысла извлекать все поля, поскольку вы их не используете.

Garry Shutler 10.01.2009 01:48

Присоединиться, как правило, быстрее, но, конечно, вам всегда нужно иметь профиль, чтобы знать наверняка.

Joel Coehoorn 10.01.2009 01:56

Оптимизатор запросов, вероятно, все равно его оптимизирует.

recursive 10.01.2009 01:56

@Garry Я сам всегда использую "1" в подзапросах "EXISTS", но подумал, что это может сбить с толку людей в этом ответе. Я не уверен, что это имеет значение для более продвинутых механизмов SQL.

Matt Hamilton 10.01.2009 01:56

@ рекурсивно должно, но не всегда. В этом случае переписать просто, но они могут стать довольно сложными, поскольку любой произвольный запрос может находиться внутри «существует», и неясно, как оценивать стоимость существующего списка по сравнению с объединением. Так что оптимизатор может этого не увидеть. Особенно оптимизатор mysql ...

SquareCog 10.01.2009 02:34
SELECT * FROM table_A 
LEFT OUTER JOIN table_B 
    ON (locate(table_b.column, UPPER(table_a.column)) == 1)
WHERE table_b.column IS NULL

Другие вопросы по теме