有没有人有想法如何比较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,我只是希望两个查询之间的所有公共列具有相同的值。
由于
答案 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