有没有办法将查询的整个结果集与另一个查询的结果集进行比较?
变得更加清晰:我已经实现了一个进程来执行多个数据比较,例如“比较表X中的记录数与表Y中的记录数”,“比较平均数量表格与预期平均金额X“,”将表Y中每一天的第X列的值与年平均金额进行比较“等等。
现在,我需要实现的内容如下:针对给定时间跨度的表执行多列查询。然后对表执行相同的查询(相同的结构)第二次。然后比较两个查询结果的每一行的每个单元格,并仅输出具有差异的行(理想情况下,标记WHICH单元格已更改)。
并且 - 好像它不够复杂 - 查询不是静态的!意味着我使用不同数量的列定义了大量查询以进行各种检查。然后对这些查询进行参数化(时间跨度等),然后比较定义的“查询对”的结果......
关于如何实施它的任何想法?作为第一步,我已经很高兴知道如何实现这个表/矩阵比较...
答案 0 :(得分:2)
在一般分析结果集时,SQL-Server不是很有用。有动态SQL,有 - tatatataaaaa! - XML。我非常感谢XML处理未知集合的能力!
以下代码会将结果集拆分为 key-name-value tupels,您可以轻松地将值按值进行比较:
两个虚拟表。数据非常相似,但存在差异:
DECLARE @tbl1 TABLE(ID INT,Value1 VARCHAR(10),Value2 VARCHAR,PointInTime DATETIME);
INSERT INTO @tbl1 VALUES
(1,'a','b',{d'2017-01-01'})
,(2,'a','b',{d'2017-01-02'})
,(3,'a','x',{d'2017-01-03'})
,(4,NULL,'b',{d'2017-01-04'})
DECLARE @tbl2 TABLE(ID INT,Value1 VARCHAR(10),Value2 VARCHAR,PointInTime DATETIME);
INSERT INTO @tbl2 VALUES
(1,'a','b',{d'2017-01-01'})
,(2,NULL,'b',{d'2017-01-02'})
,(3,'a','x',{d'2017-01-03'})
,(4,'y','b',{d'2017-01-05'});
- 这将从第一个表
创建一个XMLDECLARE @xml1 XML=
(
SELECT *
FROM @tbl1 AS tbl
FOR XML RAW,ELEMENTS XSINIL,TYPE
);
- 检查输出
/*
SELECT @xml1;
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ID>1</ID>
<Value1>a</Value1>
<Value2>b</Value2>
<PointInTime>2017-01-01T00:00:00</PointInTime>
</row>
[...more rows..]
*/
- 与第二张表相同
DECLARE @xml2 XML=
(
SELECT *
FROM @tbl2 AS tbl
FOR XML RAW,ELEMENTS XSINIL,TYPE
);
- 我们必须告诉SQL-Server后续连接的行ID的名称
DECLARE @rowIDName NVARCHAR(100)=N'ID';
- 两个CTE创建一个ID-Name-Value tupels列表,可以轻松比较
WITH AllVals1 AS
(
SELECT nd.value(N'(../*[local-name()=sql:variable("@rowIDName")])[1]',N'nvarchar(max)') AS RowID
,nd.value(N'local-name(.)',N'nvarchar(max)') AS ElementName
,nd.value(N'.',N'nvarchar(max)') AS ElementValue
FROM @xml1.nodes(N'/row/*') AS A(nd)
)
,AllVals2 AS
(
SELECT nd.value(N'(../*[local-name()=sql:variable("@rowIDName")])[1]',N'nvarchar(max)') AS RowID
,nd.value(N'local-name(.)',N'nvarchar(max)') AS ElementName
,nd.value(N'.',N'nvarchar(max)') AS ElementValue
FROM @xml2.nodes(N'/row/*') AS A(nd)
)
SELECT v1.RowID,v1.ElementName,v1.ElementValue AS V1,v2.ElementValue AS V2
FROM AllVals1 AS v1
FULL OUTER JOIN AllVals2 AS v2 ON v1.RowID=v2.RowID AND v1.ElementName=v2.ElementName
WHERE v1.ElementValue<>v2.ElementValue
结果显示,在第2行中,“Value1”为“a”,现在为空,在第4行中,“Value1”为空,现在为“y”,“PointInTime不同:
RowID ElementName V1 V2
2 Value1 a
4 Value1 y
4 PointInTime 2017-01-04T00:00:00 2017-01-05T00:00:00