Лучше включить код вопроса, а не двусмысленные текстовые данные, чтобы мы все работали с одними и теми же данными. Вот пример схемы и данных я предположил:
CREATE TABLE tbl_data (
id INT NOT NULL,
code_1 CHAR(2),
code_2 CHAR(2)
);
INSERT INTO tbl_data (
id,
code_1,
code_2
)
VALUES
(1, 'AB', 'BC'),
(2, 'BC', NULL),
(3, 'DE', 'EF'),
(4, NULL, 'BC');
Blorgbeard Как прокомментировал, предложение в своем решении DISTINCT
нет необходимости, поскольку оператор UNION
устраняет повторяющиеся строки. Существует оператор UNION ALL
, который не устраняет дубликаты, но здесь это не подходит.
Переписав запрос без предложения DISTINCT
является прекрасным решением этой проблемы:
SELECT code_1
FROM tbl_data
WHERE code_1 IS NOT NULL
UNION
SELECT code_2
FROM tbl_data
WHERE code_2 IS NOT NULL;
Это не имеет значения, что два столбца в одной таблице. Решение будет таким же, даже если столбцы были в разных таблицах.
Если вам не нравится избыточность с указанием же положения фильтра в два раза, вы можете инкапсулировать запрос накидного в виртуальной таблице перед фильтрацией, что:
SELECT code
FROM (
SELECT code_1
FROM tbl_data
UNION
SELECT code_2
FROM tbl_data
) AS DistinctCodes (code)
WHERE code IS NOT NULL;
Я считаю, синтаксис второй более уродливого , но он логически более аккуратный. Но какой из них лучше работает?
Я создал sqlfiddle, подтверждающие, что оптимизатор запросов в SQL Server 2005 производит один и тот же план выполнения для двух различных запросов:
Если SQL Server генерирует один и тот же план выполнения двух запросов, то они практически так же логически эквивалентны.
Сравним выше плана выполнения для запроса в вашем вопросе:
DISTINCT
положение делает SQL Server 2005 выполняет избыточную операцию сортировки, потому что оптимизатор запросов не знает, что все дубликаты отфильтрованный DISTINCT
в первом запросе, в любом случае будет отфильтрован UNION
.
Этот запрос логически эквивалентен двум другим, но избыточная операция делает его менее эффективным. В большом наборе данных я ожидаю, что ваш запрос займет больше времени, чтобы вернуть результирующий набор, чем два здесь. Не верьте мне на слово; экспериментируйте в своей собственной среде, чтобы быть уверенным!
Эта структура таблицы дает мне ощущение, что ваша БД не нормализована ... – gdoron
Вам не нужен 'отдельный' в первом запросе -' union' сделает это за вас. – Blorgbeard
@gdoron: коды соответствуют различным обозначениям, которые действительно могут быть повторены, то есть конкретная запись может иметь BC и BC для кодов 1 и 2. Обозначение кода 1 по сравнению с 2 также является значительным. Для разных кодов есть таблица поиска таблиц третьего стола. Не самое лучшее, но это то, с чем я имею дело. – regulus