(T-SQL)如何查询审计表,并查找2个日期之间的更改

问题描述 投票:0回答:3

审计表如下所示:

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,尽管间歇性的变化。

如何查询支付类型在2个日期之间变化的VendorID?

谢谢!

sql-server tsql audit
3个回答
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
投票
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
投票

这是一个不使用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 |
© www.soinside.com 2019 - 2024. All rights reserved.