2017-02-21 7 views
1

クエリの結果セット全体を別のクエリの結果セットと比較する方法はありますか?2つのクエリ結果のマトリックスのような比較

もう少し明確になるために:「テーブルXのレコード数とテーブルYのレコード数を比較する」、「平均値を比較する」などのいくつかのデータ比較を実行するプロセスを実装しました。期待平均金額Xに対するテーブル "、"年の各日に対するテーブルYの列Xの値を平均年間金額と比較する "などのように、

ここで実装する必要があるのは、次のとおりです。指定された期間のテーブルに対して複数列のクエリを実行します。次に、テーブルに対して同じクエリ(同じ構造体)を2回目のタイムスパンで実行します。次に、両方の照会結果の各行の各セルを比較して、差異のある行のみを出力します(理想的には、セルが変更されたフラグ)。

- 複雑ではないように、クエリは静的ではありません。さまざまなチェックのためにさまざまな数の列を持つ多数のクエリを定義することを意味します。これらのクエリは次にパラメータ化され(タイムスパンなど)、定義された "クエリペア"の結果が比較されます。

実装方法についてのアイデアはありますか?最初のステップとして、このテーブル/マトリックスの比較を実装する方法を知っていれば幸いです。

+0

リード[ '以外について'](https://msdn.microsoft.com/en-us/library/ms188055.aspx) –

+0

@ZoharPeled良いヒントですが、違いがあれば 'EXCEPT'はすべての行を返します。多くの列で、責任ある価値を見つけるのは難しいでしょう。 – Shnugo

答えて

2

SQL Serverは、結果セットを総称的に分析するのにはあまり役に立ちません。動的なSQLがあり、そこにはありますか? - XML。私は、未知のセットを扱うXMLの能力に本当に感謝しています!

2つのダミーテーブル:

次のコードを使用すると、簡単に値で値を比較することができキーの名前と値 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'}); 

- このはモミテーブル

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を作成します。第2表

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

T-SQL Serverのあとで--TwoのCTEが簡単に

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、のリストを作成

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

に参加するための行のIDの名前を教えて結果が示すように、それが行2「値1」の「」であり、現在、空であり、行の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

関連する問題