2012-02-10 3 views
1

есть ли у кого-нибудь идеи, как сравнить результат двух запросов, имеющих одинаковые имена колонок, но в другом порядке?TSQL Сравнить результат из 2 запросов

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

[EDIT]

Чтобы быть более конкретным, мне нужно сравнить значение каждой строки и каждого столбца (с тем же именем) из 2-х различных запросов.

Пример:

результат запроса 1:

A|B|C|D 
1|4|7|11 
2|5|8|21 
3|**6**|9|31 

результат запроса 2:

A|B |D 
1|4 |11 
2|5 |21 
3|**99**|31 

В этом случае, хотелось бы, чтобы обнаружить, что Query2 на 3о строке в столбце В, имеют другое значение. Мне все равно, что у Query2 нет столбца C, я просто хочу, чтобы все общие столбцы между двумя запросами имели одинаковые значения.

Благодаря

+1

Какого типа сравнения вы хотели сделать? –

+0

Сравните как? Найти все строки в A, которые не находятся в B? –

+0

Нужна дальнейшая информация здесь ... слишком универсальная ... на этом уровне нельзя сказать много. – judda

ответ

3

С учетом этих таблиц и данных:

USE tempdb; 
GO 

CREATE TABLE dbo.TableA 
(
    A INT, 
    B INT, 
    C INT, 
    D INT 
); 

CREATE TABLE dbo.TableB 
(
    A INT, 
    D INT, 
    B INT 
); 

INSERT dbo.TableA SELECT 1,4,7,11 
    UNION ALL SELECT 2,5,8,21 
    UNION ALL SELECT 3,6,9,31; 

INSERT dbo.TableB SELECT 1,11,4 
    UNION ALL SELECT 2,21,5 
    UNION ALL SELECT 3,31,99; 

Что вы, кажется, ищет является одним из следующих способов:

-- those where at least one column doesn't match: 
SELECT A,B,D FROM dbo.TableA 
EXCEPT 
SELECT A,B,D FROM dbo.TableB; 

Результаты (от A стороны):

A B D 
---- ---- ---- 
3 6 31 

OR

-- those where all columns DO match: 
SELECT A,B,D FROM dbo.TableA 
INTERSECT 
SELECT A,B,D FROM dbo.TableB; 

Результаты:

A B D 
---- ---- ---- 
1 4 11 
2 5 21 

Если вы не знаете, столбцы или не хотите писать их вручную, вы можете сделать это с помощью динамического SQL, просто передавая два имени таблицы (со схемой) в переменные. Обратите внимание, что это не ловушка для ошибок, которые произойдут, если no столбцы разделяются двумя таблицами или существуют те же имена столбцов, но имеют несовместимые типы данных. Эта обработка ошибок легко добавить, если вы хотите сделать решение более надежным.

DECLARE 
    @sql NVARCHAR(MAX), 
    @cols NVARCHAR(MAX), 
    @t1 NVARCHAR(511), 
    @t2 NVARCHAR(511); 

SELECT 
    @sql = N'', 
    @cols = N'', 
    @t1 = N'dbo.TableA', 
    @t2 = N'dbo.TableB'; 

SELECT @cols = @cols + ',' + a.name 
    FROM sys.columns AS a 
    INNER JOIN sys.columns AS b 
    ON a.name = b.name 
    WHERE a.[object_id] = OBJECT_ID(@t1) 
    AND b.[object_id] = OBJECT_ID(@t2); 

SET @cols = STUFF(@cols, 1, 1, N''); 

-- those where at least one column doesn't match: 
SELECT @sql = N'SELECT ' + @cols + ' 
    FROM ' + @t1 + ' EXCEPT 
    SELECT ' + @cols + ' FROM ' + @t2 + ';'; 

EXEC sp_executesql @sql; 

-- those where all columns DO match: 
SELECT @sql = N'SELECT ' + @cols + ' 
    FROM ' + @t1 + ' INTERSECT 
    SELECT ' + @cols + ' FROM ' + @t2 + ';'; 

EXEC sp_executesql @sql; 

Не забудьте очистить:

DROP TABLE dbo.TableA, dbo.TableB; 
+0

спасибо. Я попробую ваше решение. – muek

+0

Ну, вы не должны принимать решение, пока не попробуете его, и подтвердите, что он сработал. :-) –

+0

Ваше решение будет работать. Чтобы сделать его более гибким, знаете ли вы, как получить имена столбцов из функции таблицы? Я знаю, как получить его из таблицы, но не из функции таблицы. – muek

2

Вы можете обернуть ваши запросы как подзапросы, а затем повторно столбцы в любом порядке.

+0

Вы правы, но оба запроса имеют разные количество столбцов Я бы сделал сравнение, не подтвердив, если все столбцы находятся в одном порядке. Я говорю о 50 столбцах. – muek

+0

RedFilter прав - это t он лучший способ сделать это. Если вы не выписываете запрос, тогда вы, вероятно, просто ленитесь. (извините) –

+0

@Norla, вероятно, вы правы, но я не хочу поддерживать 30 запросов, которые постоянно меняются. Хороший программист должен быть немного ленив: D – muek

0

Вы можете сделать это только один шаг:

SELECT * 
FROM (
     --compare query a vs query b 
    SELECT ad.id_addetto,'not in b'y 
    FROM addetti ad 
    WHERE ad.id_addetto < 125 -- query a 
    EXCEPT 
    SELECT ad.id_addetto,'not in b'y 
    FROM addetti ad 
    WHERE ad.id_addetto < 166 -- query b 
    UNION 
    --compare query b vs query a 
    SELECT ad.id_addetto, 'not in a'y 
    FROM addetti ad 
    WHERE ad.id_addetto < 166 -- query b 
    EXCEPT 
    SELECT ad.id_addetto ,'not in a'y 
    FROM addetti ad 
    WHERE ad.id_addetto < 125 -- query a 
    ) xx 
Смежные вопросы