2017-11-01 17 views
0

監査テーブル間の変更を見つけるために(T-SQL)は次のようになります。この例ではがどのように監査テーブルを照会し、2日付

Audit ID VendorID  PaymentType  CreateDateUTC 
999  8048   2    2017-10-30-08:84:24 
1000  1234   5    2017-10-31-01:17:34 
1001  8048   7    2017-10-31-01:17:45 
1002  1234   5    2017-10-31-01:17:53 
1003  1234   7    2017-10-31-01:18:23 
1004  1234   5    2017-11-01-01:18:45 

、あなたが言うことがわかります - 1234 PaymentTypeとしてスタートしVENDORID 5、まだ5の別のエントリがあります(監査テーブルにはクエリに関連しない追加の変更が記録されます)。その後7に変更されますが、5に戻ります。

質問に回答したい: '現在の日付とXの間に、これらのベンダーIDにPaymentTypeが変更されました。'ボーナスは、これは以前のPaymentTypeでした。

期待される結果:00:00、私は変わったと、それはベンダーID 8048返すようにしたい(とボーナスとして思い、

VendorID PaymentType Prev_PaymentType 
8048  7   2 

は、だから私は今と10-31-01の間で照会した場合を言います以前のPaymentTypeは2)でしたが、2017-10-31-01:00:00にVendorID 1234が表示されるべきではなく、間欠的な変更にもかかわらず5であり、現在は5です。

2つの日付間で支払いタイプが変更されたVendorIDをクエリするにはどうすればよいですか?

ありがとうございます!

+1

あなたは** [編集](httpsの場合、それは偉大な説明になります/スタックオーバーフロー。com/posts/47065050/edit)**あなたの質問と、フォーマットされたテキストとして期待される結果を追加してください。 – Sami

+0

追加していただきありがとうございます。 – bbb0777

答えて

1

が代替であります私の証明が有用であることに近づき、OUTER APPLYを使用します。 AuditID列は、サンプル・データにdatetime値がないため、タイ・ブレーカーとして使用されることに注意してください。

SQL Fiddle

CREATE TABLE AuditTable (
     AuditID int 
    , VendorID int 
    , PaymentType int 
    , CreateDateUTC date 
); 

INSERT INTO AuditTable 
     VALUES (999, 8048, 2, '2017-10-30'), 
     (1000, 1234, 5, '2017-10-31'), 
     (1001, 8048, 7, '2017-10-31'), 
     (1002, 1234, 5, '2017-10-31'), 
     (1003, 1234, 7, '2017-10-31'), 
     (1004, 1234, 5, '2017-11-01'); 

クエリ1

select 
* 
from AuditTable a 
outer apply (
    select top(1) PaymentType, CreateDateUTC 
    from AuditTable t 
    where a.VendorID = t.VendorID 
    and a.CreateDateUTC >= t.CreateDateUTC 
    and a.AuditID > t.AuditID 
    order by CreateDateUTC DESC, AuditID DESC 
) oa (PrevPaymentType, PrevDate) 
order by 
     vendorid 
    , CreateDateUTC 

Results:/:

| AuditID | VendorID | PaymentType | CreateDateUTC | PrevPaymentType | PrevDate | 
|---------|----------|-------------|---------------|-----------------|------------| 
| 1000 |  1234 |   5 | 2017-10-31 |   (null) |  (null) | 
| 1002 |  1234 |   5 | 2017-10-31 |    5 | 2017-10-31 | 
| 1003 |  1234 |   7 | 2017-10-31 |    5 | 2017-10-31 | 
| 1004 |  1234 |   5 | 2017-11-01 |    7 | 2017-10-31 | 
|  999 |  8048 |   2 | 2017-10-30 |   (null) |  (null) | 
| 1001 |  8048 |   7 | 2017-10-31 |    2 | 2017-10-30 | 
1
CREATE TABLE AuditTable (
    AuditID  INT, 
    VendorID INT, 
    PaymentType INT,  
    CreateDateUTC DATE 
    ); 

INSERT INTO AuditTable VALUES 
(999 ,  8048,   2,    '2017-10-30'), 
(1000,  1234,   5,    '2017-10-31'), 
(1001,  8048,   7,    '2017-10-31'), 
(1002,  1234,   5,    '2017-10-31'), 
(1003,  1234,   7,    '2017-10-31'), 
(1004,  1234,   5,    '2017-11-01'); 

WITH CTE AS (
SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY CreateDateUTC ORDER BY PaymentType) AS N1 

FROM AuditTable 
WHERE CreateDateUTC <= '2017-11-02' AND CreateDateUTC >= '2017-10-01' 
    ) , 
    MAXP AS(
      SELECT VendorID, PaymentType, CreateDateUTC 
      FROM CTE 
      WHERE N1 = (SELECT MAX(N1) FROM CTE) 
     ) 
    SELECT TOP 1 MAXP.VendorID, MAXP.PaymentType AS PaymentType, CTE.PaymentType AS Prev_PaymentType 
    FROM MAXP 
     JOIN CTE ON CTE.VendorID = MAXP.VendorID; 

結果:ここで

+----------+-------------+------------------+ 
| VendorID | PaymentType | Prev_PaymentType | 
+----------+-------------+------------------+ 
|  8048 |   7 |    2 | 
+----------+-------------+------------------+ 

Demo

+0

ありがとう、私は誤ったコミュニケーションだと思う:それは現在の、そして最初の支払いタイプを示すだろう。しかし、1)特定の日から現在までの全体的な変化を見ることはできません。 2)目的は、日付を入力するより多くの場合はVendorIDを入力し、返されたVendorIDを取得する必要があります。 – bbb0777

+0

@ mmace31日付で照会し、 '1234 5 'と' 8048 2'を取得することを意味しますか? – Sami

+0

いいえ、彼は、彼が2017年から1031年までの間、今の時代のベンダーの地位が今のところとは違うことを望むことを意味していると思います。だから1234はリストされません。しかし、8048はそうです。 – Dijkgraaf

0

LEAD()またはLAG()を使用せずに変形であるが、ROW_NUMBERCOUNT() OVER()を使用しません。

でこのverision作業を参照してください:SQL Fiddle

CREATE TABLE AuditTable (
     AuditID int 
    , VendorID int 
    , PaymentType int 
    , CreateDateUTC date 
); 

INSERT INTO AuditTable 
     VALUES (999, 8048, 2, '2017-10-30'), 
     (1000, 1234, 5, '2017-10-31'), 
     (1001, 8048, 7, '2017-10-31'), 
     (1002, 1234, 5, '2017-10-31'), 
     (1003, 1234, 7, '2017-10-31'), 
     (1004, 1234, 5, '2017-11-01'); 

クエリ1

WITH 
     rowz AS (
        SELECT * 
         , ROW_NUMBER() OVER (PARTITION BY VendorID 
              ORDER BY CreateDateUTC, AuditID) AS lagno 
        FROM AuditTable 
      ), 
     cte AS (
        SELECT * 
         , ROW_NUMBER() OVER (PARTITION BY VendorID, CreateDateUTC 
              ORDER BY c DESC, span_dt) rn 
        FROM (
         SELECT r1.AuditID, r1.VendorID, r1.CreateDateUTC 
           , r1.PaymentType AS prevpaymenttype 
           , r2.PaymentType 
           , COALESCE(r2.CreateDateUTC, CAST(GETDATE() AS date)) span_dt 
           , COUNT(*) OVER (PARTITION BY r1.VendorID, r1.CreateDateUTC, r1.PaymentType) c 
         FROM rowz r1 
         LEFT JOIN rowz r2 ON r1.VendorID = r2.VendorID 
           AND r1.lagno = r2.lagno - 1 
       ) d 
      ) 
SELECT 
     AuditID, VendorID, PrevPaymentType, PaymentType, CreateDateUTC 
FROM (
     SELECT 
      * 
     FROM cte 
     WHERE ('20171031' BETWEEN CreateDateUTC AND span_dt AND rn = 1) 
     OR (CAST(GETDATE() AS date) BETWEEN CreateDateUTC AND span_dt AND rn = 1) 
) d 
WHERE PaymentType <> PrevPaymentType 

Results:ここ

| AuditID | VendorID | PrevPaymentType | PaymentType | CreateDateUTC | 
|---------|----------|-----------------|-------------|---------------| 
|  999 |  8048 |    2 |   7 | 2017-10-30 | 
+0

ああ、私はそのことを賭けましたが、本当に残念です。私はSQL Server 2008を使用しており、LEAD/LAGは2012年までサポートされていません。それは驚くほどに見える...! – bbb0777

+0

LEAD/LAGを使用しないように再加工しました –

+0

過去からのブラスト:だから1)これはすばらしい2)私たちの監査テーブルは何もしない支払い状況が変更されます。したがって、r2.lagno-1は同じ支払いステータスである可能性がありますが、その1つ(またはその背後の2つ)の背後にある実際の変更は、 'AND r1.lagno = r2.lagno - 1'の部分が機能しない可能性があります。何かご意見は? – bbb0777

関連する問題