TSQL比较2个查询的结果

时间:2012-02-10 20:13:43

标签: sql-server sql-server-2005 tsql

有没有人有想法如何比较2个查询的结果,这些查询具有相同的列名,但顺序不同?

我知道如果我有两个查询以相同的顺序返回相同的列,我可以使用除外,情况并非如此。

[编辑]

更具体地说,我需要比较来自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

在这种情况下,我想检测B列中3º行的Query2,具有不同的值。 我不在乎Query2没有列C,我只是希望两个查询之间的所有公共列具有相同的值。

由于

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分:2)

您可以将查询包装为子查询,然后按所需的任何顺序选择列。

答案 2 :(得分: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