2017-02-21 2 views
1

다른 쿼리의 결과 집합에 대해 쿼리의 전체 결과 집합을 비교할 수 있습니까?두 쿼리 결과의 매트릭스 형 비교

조금 더 명확 해지기 위해 : "표 X의 레코드 수를 표 Y의 레코드 수와 비교", "평균 값 비교"와 같은 여러 데이터 비교를 수행하는 프로세스를 구현했습니다. 예상 평균 금액 X에 대한 테이블 ","연도의 각 요일에 대한 테이블 Y의 X 열의 값을 평균 연간 금액과 비교 "등이 있습니다.

이제 구현해야 할 것은 다음과 같습니다. 주어진 시간 범위에 대해 테이블에 대해 다중 열 쿼리를 수행하십시오. 그런 다음 두 번째 시간 범위에 대해 동일한 쿼리 (동일한 구조)를 테이블에 대해 수행하십시오. 그런 다음 두 쿼리 결과의 각 행의 각 셀을 비교하고 차이가있는 행만 출력합니다 (이상적으로 셀이 변경된 플래그가있는 것이 이상적입니다).

마치 복잡하지 않은 것처럼 - 쿼리가 정적이 아닙니다! 다양한 검사를 위해 다양한 수의 열로 수많은 쿼리를 정의합니다. 이러한 쿼리는 다음 매개 변수 (timespan 등) 및 정의 된 "쿼리 쌍"의 결과를 비교해야합니다 ...

그것을 구현하는 방법에 대한 아이디어? 첫 번째 단계로서 나는이 테이블/행렬 비교를 구현하는 방법을 이미 알고 행복합니다 ...

+0

읽기 ['제외 대해서 '] (https://msdn.microsoft.com/en-us/library/ms188055.aspx) –

+0

@ZoharPeled 좋은 힌트지만 차이가있는 곳이면 모든 행에 대해 'EXCEPT'가 반환됩니다. 많은 컬럼을 통해 책임있는 가치를 찾기가 어려울 것입니다 ... – Shnugo

답변

2

SQL Server는 일반적으로 결과 집합을 분석 할 때별로 도움이되지 않습니다. 동적 인 SQL이 있고 - tatatataaaaa가 있습니다! - XML. 알 수없는 세트를 다루는 XML의 능력에 정말 감사드립니다!

두 더미 테이블 :

다음 코드는 쉽게 값에 의해 값을 비교할 수 있습니다 키 - 이름 - 값 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'}); 

--This이 전나무 테이블

DECLARE @xml1 XML= 
(
    SELECT * 
    FROM @tbl1 AS tbl 
    FOR XML RAW,ELEMENTS XSINIL,TYPE 
); 

--check 출력

/* 
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..] 
*/ 

--Same과에서 XML을 생성합니다 두 번째 표

DECLARE @xml2 XML= 
(
    SELECT * 
    FROM @tbl2 AS tbl 
    FOR XML RAW,ELEMENTS XSINIL,TYPE 
); 

- 우리는 t는

DECLARE @rowIDName NVARCHAR(100)=N'ID'; 

--Two 열팽창 계수가

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 

쉽게 비교할 수 있습니다 ID - 이름 - 값 tupels의 목록을 작성, 행의 ID의 이름이 나중에 조인 SQL-서버에게 결과 프로그램은, 그 행 2 "값 1"에서 "A"이고 현재 비어 있고 4 열 "값 1은"비어 이제 "Y"이고 "POINTINTIME가 다릅니다

RowID ElementName V1     V2 
2  Value1  a 
4  Value1       y 
4  PointInTime 2017-01-04T00:00:00 2017-01-05T00:00:00 
+0

위대한, 그것을 시도해 줄 것입니다! 유망 해 보인다. :-) 미리 감사드립니다. 테스트를 마친 후 결과를 다시 보겠습니다.:-) – Tyron78

+0

아주 좋아 보인다. 최소한이 작업의 큰 부분을 해결하는 것이 도움이됩니다. 불행히도 Microsoft APS/PDW는 FOR XML을 지원하지 않지만 이는 다른 것입니다. 지원해 주셔서 감사합니다. 일부 PDW/APS/"no-XML"접근법을 우연히 발견한다면 알려주십시오. :-) – Tyron78

+0

이봐, 큰 테이블로 테스트 해봤 니? 테이블 당 10k 레코드와 같은 성능으로 정말 나쁜 성능이 발생했습니다. 하지만 이미이 문제를 해결하기 위해 SSIS C# 구성 요소를 구현했습니다. :-) – Tyron78