Альтернатива SQL Union - PullRequest
       10

Альтернатива SQL Union

0 голосов
/ 02 июля 2018

У меня есть список номеров. Я хочу определить, в какой таблице они находятся, из списка из трех таблиц и вернуть имя таблицы и номер в одном наборе результатов.

Nums: 1,2,3,4,8,9
Tables: tb1, tb2, tb3

Как правило, я бы запрашивал каждую таблицу и Union все вместе, но я хочу знать, есть ли способ, чтобы операторы уменьшали список, поскольку он, как мы надеемся, повысит эффективность большого объема данных. Вот пример того, что я хочу сделать:

Checking tb1 first, I find that 1,2,3 are present.
Then check tb2 for the remaining numbers (4,8,9).
If none of the numbers are found, then check tb3, otherwise the query should end.

Вот два возможных возврата:

TableName | Num        *|*       TableName | Num
----------------       *|*       ----------------
tb1       | 1          *|*       tb1       | 1
tb1       | 2          *|*       tb1       | 2
tb1       | 3          *|*       tb1       | 3
tb3       | 4          *|*       tb2       | 4
tb3       | 8          *|*       tb3       | 9
tb3       | 9          *|*       *** 8 wasn't found

Есть ли способ сделать это, или Union все еще лучший способ?

1 Ответ

0 голосов
/ 02 июля 2018

Просто для удовольствия я написал два запроса, один с использованием метода UNION, а другой попытался использовать логику, которую вы определили выше, то есть проверить таблицу1, затем поискать оставшиеся элементы в таблице2, затем в таблице3 и т. Д.

Это был мой сценарий:

DECLARE @table1 TABLE (id INT PRIMARY KEY);
DECLARE @table2 TABLE (id INT PRIMARY KEY);
DECLARE @table3 TABLE (id INT PRIMARY KEY);
INSERT INTO @table1 SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 9;
INSERT INTO @table2 SELECT 3 UNION ALL SELECT 4;
INSERT INTO @table3 SELECT 6 UNION ALL SELECT 8;
SELECT id, 'table1' AS found FROM @table1 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
UNION
SELECT id, 'table2' AS found FROM @table2 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
UNION
SELECT id, 'table3' AS found FROM @table3 WHERE id IN (1, 2, 3, 4, 5, 6, 7, 8, 9)
ORDER BY id;

DECLARE @search TABLE (id INT PRIMARY KEY);
INSERT INTO @search SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9;
WITH 
    nt1 AS (SELECT * FROM @search s EXCEPT SELECT * FROM @table1),
    nt2 AS (SELECT * FROM nt1 EXCEPT SELECT * FROM @table2)
SELECT s.id, 'table1' AS found FROM (SELECT * FROM @search INTERSECT SELECT * FROM @table1) s
UNION ALL
SELECT s.id, 'table2' AS found FROM (SELECT * FROM nt1 INTERSECT SELECT * FROM @table2) s
UNION ALL
SELECT s.id, 'table3' AS found FROM (SELECT * FROM nt2 INTERSECT SELECT * FROM @table3) s
ORDER BY id;

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

Затем я рассмотрел весь сценарий как план выполнения. Это не ракетостроение, и есть довольно веский аргумент, что введение новой таблицы @search - это «обман», а также то, что использование табличных переменных для хранения данных является неправильным (следует использовать физические таблицы, даже если они временные), и что объем данных в моих таблицах слишком мал и т. д.

Однако в этом некорректном эксперименте я обнаружил, что метод UNION был более чем в два раза быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...