В SQL Server, как фильтровать множество элементов по нескольким столбцам

У меня есть таблица t1 со столбцами, такими как name, code1, code2,..., code20

Есть, скажем, 100 тысяч строк.

У меня есть другая таблица поиска, t2, которая имеет один столбец, code; он имеет 10 тыс. строк, и каждая строка имеет код. Итак, всего в этой таблице с 1 столбцом 10 тысяч кодов.

Мне нужно отфильтровать все строки в t1, которые имеют коды в t2 из любого столбца, то есть столбцы с code1 по code20. Другими словами, в каждой строке в t1, как только столбец имеет один из кодов в t2, он должен быть захвачен.

Есть простой способ сделать это? Большое спасибо!


person user3306972    schedule 28.04.2014    source источник
comment
Это довольно забавный дизайн БД. Можно ли немного изменить схему?   -  person Abe Miessler    schedule 29.04.2014
comment
Был бы простой способ, если бы у вас был правильный дизайн базы данных - например. если бы вы связали t1 со списком кодов через отношение 1:n (вместо того, чтобы иметь Code1...Code20 в таблице t1). К чему эта хреновая конструкция, простого пути нет.....   -  person marc_s    schedule 29.04.2014


Ответы (2)


Вот как это сделать с помощью not exists:

select t1.*
from t1
where not exists (select 1
                  from t2
                  where t2.code = t1.code1 or
                        t2.code = t1.code2 or
                        . . .
                        t2.code = t1.code20
                 );

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

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

person Gordon Linoff    schedule 28.04.2014

Похоже, вам нужно повернуть данные в таблице t1, а затем присоединиться к t2. Таким образом, вместо t1, где у вас есть имя, код1, код2,... код 20, вы должны повернуть t1 только к столбцам имени и кода, а затем присоединиться к t2. В качестве альтернативы вы можете просто выполнить отдельные соединения t1 с t2 для каждого из столбцов t2 с кодом от 1 до 20 и объединить результат. Это если я правильно понимаю вашу проблему.

person Johnny Fitz    schedule 28.04.2014
comment
Ответ Гордона лучше, чем мое решение для соединения, но я думал, что он ищет совпадения. Небольшой вопрос: должен ли приведенный выше код не существовать, а не существовать? Я думал, он хочет захватить спички - person Johnny Fitz; 29.04.2014