(T-SQL)如何查询审计表,并查找2个日期

时间:2017-11-01 23:07:09

标签: sql-server tsql audit

审计表如下所示:

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

在这个例子中,您可以看到 - VendorID 1234作为PaymentType 5启动,然后有另一个条目,它仍然是5(审计表记录了与我的查询无关的其他更改),然后它变为7,但随后回到5。

说我想回答这个问题:'从现在到日期X,这些VendorID在PaymentType上有变化'。奖金是 - 这是之前的PaymentType。

预期结果:

VendorID  PaymentType  Prev_PaymentType
8048      7            2

所以说如果我现在和10-31-01:00:00之间询问,我希望它返回VendorID 8048,因为它已经改变了(作为奖励,它之前的PaymentType是2),但是VendorID 1234不应该出现,因为在2017-10-31-01:00:00它是一个5,现在仍然是5,尽管间歇性的变化。

如何查询两个日期之间付款类型发生变化的VendorID?

谢谢!

3 个答案:

答案 0 :(得分:2)

使用OUTER APPLY,这是我证明有用的替代方法。请注意,AuditID列主要用作平局,因为样本数据没有日期时间值。

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 :(得分: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

答案 2 :(得分:0)

以下是不使用LEAD()LAG()但使用ROW_NUMBERCOUNT() OVER()的变体。

请在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 |