-1

我正在处理一个大型 SQL 表、186 列、257899 行,并且还在计数。每次在主数据中更改某些内容时都会添加它。这是shadow表格的一部分,允许我们查看不同字段发生的审计历史记录。

我需要做的是查看谁更新、何时更新以及特定的更新顺序。我需要随时找到某个 3 个用户更新了主表以从

  • 比尔 => 活跃
  • 账单 => 没有账单
  • 活动 => 进行中

我需要收集的是

  1. 正在切换的状态以及切换到的内容(来自上面的列表)
  2. 从以下 3 个用户列表中进行更新的用户名称
  3. 更新日期时间
  4. 索赔号

我正在寻找的用户我不能给出他们的名字,所以我们会选择:

  • 用户 1
  • 用户 2
  • 用户 3

我最近了解了在 SQL 中以基于集合的方式做事,但我还没有完全弄清楚这一点。我知道我可以遍历表格并查找单个用户的任何更新,然后遍历这些更新以查找是否有任何符合上述条件的更新,但我知道与基于集合的批准相比,这会很慢。

我才刚刚开始研究这个,所以我还没有任何代码,但我会在尝试不同的事情时更新这个问题。

我只是不知道如何去弄清楚如何使它成为一个基于集合的问题?

更新

以下是一些示例数据的样子:

创建#TestingData为数据表和#TestingTable影子表,然后填充样本数据。

create table #TestingTable(Id int,SMState varchar(50),UpdatedBy varchar(50),UpdatedOn datetime,cd_ClaimNumber varchar(50))

create table #TestingData(Id int,SMState varchar(50),UpdatedBy varchar(50),UpdatedOn datetime,cd_ClaimNumber varchar(50))

insert into #TestingData([Id],[UpdatedBy],[UpdatedOn],[cd_ClaimNumber],SMState)
Values  (1,'John Doe','2015-10-25 12:00:00',208692,'Bill'),
        (2,'John Doe','2015-10-25 12:00:00',297983,'Bill'),
        (3,'John Doe','2015-10-25 13:00:00',697920,'Bill'),        
        (4,'John Doe','2015-10-25 12:00:00',992196,'Bill')

INSERT INTO #TestingTable([Id],[UpdatedBy],[UpdatedOn],[cd_ClaimNumber],SMState) 
VALUES
      (1,'John Jones','2015-10-24 13:00:00',208692,'No Bill'),
      (2,'John Jones','2015-10-24 12:00:00',208692,'Bill'),
      (3,'John Jones','2015-10-23 12:00:00',208692,'In Progress'),
      (4,'John Jones','2015-10-22 16:00:00',208692,'Active'),
      (5,'John Jones','2015-10-22 14:00:00',208692,'No Bill'),
      (6,'John Jones','2015-10-22 12:00:00',208692,'Bill'),
      (7,'John Jones','2015-10-24 12:00:00',297983,'Bill'),
      (8,'John Jones','2015-10-23 14:00:00',297983,'Active'),
      (9,'John Jones','2015-10-23 13:00:00',297983,'In Progress'),
      (10,'John Jones','2015-10-23 12:00:00',297983,'Active'),
      (11,'John Jones','2015-10-22 12:00:00',297983,'Bill'),
      (12,'Jeffery Sampson','2015-10-24 13:00:00',697920,'No Bill'),
      (13,'Jeffery Sampson','2015-10-24 12:00:00',697920,'Bill'),
      (14,'Jeffery Sampson','2015-10-23 12:00:00',697920,'In Progress'),
      (15,'Jeffery Sampson','2015-10-22 16:00:00',697920,'Active'),
      (16,'Jeffery Sampson','2015-10-22 14:00:00',697920,'No Bill'),
      (17,'Jeffery Sampson','2015-10-22 12:00:00',697920,'Bill'),
      (18,'Jeffery Sampson','2015-10-24 12:00:00',992196,'Bill'),
      (19,'Jeffery Sampson','2015-10-23 14:00:00',992196,'Active'),
      (20,'Jeffery Sampson','2015-10-23 13:00:00',992196,'In Progress'),
      (21,'Jeffery Sampson','2015-10-23 12:00:00',992196,'Active'),
      (22,'Jeffery Sampson','2015-10-22 12:00:00',992196,'Bill')

这是使用上述数据的影子表的样子:

+----+-------------+-----------------+---------------------+----------------+
| Id |   SMState   |    UpdatedBy    |      UpdatedOn      | cd_ClaimNumber |
+----+-------------+-----------------+---------------------+----------------+
|  1 | No Bill     | John Jones      | 24.10.2015 13:00:00 |         208692 |
|  2 | Bill        | John Jones      | 24.10.2015 12:00:00 |         208692 |
|  3 | In Progress | John Jones      | 23.10.2015 12:00:00 |         208692 |
|  4 | Active      | John Jones      | 22.10.2015 16:00:00 |         208692 |
|  5 | No Bill     | John Jones      | 22.10.2015 14:00:00 |         208692 |
|  6 | Bill        | John Jones      | 22.10.2015 12:00:00 |         208692 |
|  7 | Bill        | John Jones      | 24.10.2015 12:00:00 |         297983 |
|  8 | Active      | John Jones      | 23.10.2015 14:00:00 |         297983 |
|  9 | In Progress | John Jones      | 23.10.2015 13:00:00 |         297983 |
| 10 | Active      | John Jones      | 23.10.2015 12:00:00 |         297983 |
| 11 | Bill        | John Jones      | 22.10.2015 12:00:00 |         297983 |
| 12 | No Bill     | Jeffery Sampson | 24.10.2015 13:00:00 |         697920 |
| 13 | Bill        | Jeffery Sampson | 24.10.2015 12:00:00 |         697920 |
| 14 | In Progress | Jeffery Sampson | 23.10.2015 12:00:00 |         697920 |
| 15 | Active      | Jeffery Sampson | 22.10.2015 16:00:00 |         697920 |
| 16 | No Bill     | Jeffery Sampson | 22.10.2015 14:00:00 |         697920 |
| 17 | Bill        | Jeffery Sampson | 22.10.2015 12:00:00 |         697920 |
| 18 | Bill        | Jeffery Sampson | 24.10.2015 12:00:00 |         992196 |
| 19 | Active      | Jeffery Sampson | 23.10.2015 14:00:00 |         992196 |
| 20 | In Progress | Jeffery Sampson | 23.10.2015 13:00:00 |         992196 |
| 21 | Active      | Jeffery Sampson | 23.10.2015 12:00:00 |         992196 |
| 22 | Bill        | Jeffery Sampson | 22.10.2015 12:00:00 |         992196 |
+----+-------------+-----------------+---------------------+----------------+

以下是使用上述数据的数据表:

+----+---------+-----------+---------------------+----------------+
| Id | SMState | UpdatedBy |      UpdatedOn      | cd_ClaimNumber |
+----+---------+-----------+---------------------+----------------+
|  1 | Bill    | John Doe  | 25.10.2015 12:00:00 |         208692 |
|  2 | Bill    | John Doe  | 25.10.2015 12:00:00 |         297983 |
|  3 | Bill    | John Doe  | 25.10.2015 13:00:00 |         697920 |
|  4 | Bill    | John Doe  | 25.10.2015 12:00:00 |         992196 |
+----+---------+-----------+---------------------+----------------+

我正在寻找的最终结果是这样的:

+---------------+-----------+-----------------+---------------------+-------------+
| CurrentStatus | OldStatus |    UpdatedBy    |      UpdateOn       | ClaimNumber |
+---------------+-----------+-----------------+---------------------+-------------+
| No Bill       | Bill      | John Jones      | 22.10.2015 14:00:00 |      208692 |
| In Progress   | Active    | John Jones      | 23.10.2015 12:00:00 |      208692 |
| No Bill       | Bill      | John Jones      | 24.10.2015 13:00:00 |      208692 |
| Active        | Bill      | John Jones      | 23.10.2015 12:00:00 |      297983 |
| In Progress   | Active    | John Jones      | 23.10.2015 13:00:00 |      297983 |
| No Bill       | Bill      | Jeffery Sampson | 22.10.2015 14:00:00 |      697920 |
| In Progress   | Active    | Jeffery Sampson | 23.10.2015 12:00:00 |      697920 |
| No Bill       | Bill      | Jeffery Sampson | 24.10.2015 13:00:00 |      697920 |
| Active        | Bill      | Jeffery Sampson | 23.10.2015 12:00:00 |      992196 |
| In Progress   | Active    | Jeffery Sampson | 23.10.2015 13:00:00 |      992196 |
+---------------+-----------+-----------------+---------------------+-------------+

这是我尝试过的:

with Test_1 as
( select ROW_NUMBER() over(order by pdr.cd_ClaimNumber,pdr.UpdatedOn) as RowID,* from #TestingTable pdr)
select t1.cd_ClaimNumber,t1.UpdatedOn, t1.SMState OldStatus, t2.SMState NewStatus, t1.UpdatedBy
from Test_1 t1
join Test_1 t2 on t2.RowID = t1.RowID + 1
where t1.cd_ClaimNumber = t2.cd_ClaimNumber
    and t1.SMState != t2.SMState
order by t1.cd_ClaimNumber,t2.UpdatedOn

这给了我这个结果:

+----------------+---------------------+-------------+-------------+-----------------+
| cd_ClaimNumber |      UpdatedOn      |  OldStatus  |  NewStatus  |    UpdatedBy    |
+----------------+---------------------+-------------+-------------+-----------------+
|         208692 | 22.10.2015 12:00:00 | Bill        | No Bill     | John Jones      |
|         208692 | 22.10.2015 14:00:00 | No Bill     | Active      | John Jones      |
|         208692 | 22.10.2015 16:00:00 | Active      | In Progress | John Jones      |
|         208692 | 23.10.2015 12:00:00 | In Progress | Bill        | John Jones      |
|         208692 | 24.10.2015 12:00:00 | Bill        | No Bill     | John Jones      |
|         297983 | 22.10.2015 12:00:00 | Bill        | Active      | John Jones      |
|         297983 | 23.10.2015 12:00:00 | Active      | In Progress | John Jones      |
|         297983 | 23.10.2015 13:00:00 | In Progress | Active      | John Jones      |
|         297983 | 23.10.2015 14:00:00 | Active      | Bill        | John Jones      |
|         697920 | 22.10.2015 12:00:00 | Bill        | No Bill     | Jeffery Sampson |
|         697920 | 22.10.2015 14:00:00 | No Bill     | Active      | Jeffery Sampson |
|         697920 | 22.10.2015 16:00:00 | Active      | In Progress | Jeffery Sampson |
|         697920 | 23.10.2015 12:00:00 | In Progress | Bill        | Jeffery Sampson |
|         697920 | 24.10.2015 12:00:00 | Bill        | No Bill     | Jeffery Sampson |
|         992196 | 22.10.2015 12:00:00 | Bill        | Active      | Jeffery Sampson |
|         992196 | 23.10.2015 12:00:00 | Active      | In Progress | Jeffery Sampson |
|         992196 | 23.10.2015 13:00:00 | In Progress | Active      | Jeffery Sampson |
|         992196 | 23.10.2015 14:00:00 | Active      | Bill        | Jeffery Sampson |
+----------------+---------------------+-------------+-------------+-----------------+

这不太行。它得到了所有的变化,而不仅仅是我正在寻找的那些。我的基础是Programming SQL in a Set-Based Way

4

1 回答 1

0

如果您的审计表中有适当的列,那么我认为它是非常简单的查询。当然我希望这里不会包含claimnumber,但是会有一些原始数据的引用,然后就是简单的join。但根据您的审计表结构,可能还有更多内容。

SELECT old, new, who, when, claimnumber

FROM table

WHERE (    (old = 'Bill' AND new = 'Active') 
        OR (old = 'Bill' AND new = 'No Bill')
        OR (old = 'Active' AND new = 'In Progress')) 
      AND user IN ('User1','User2','User3')

 ORDER BY when

另一个故事是拥有支持此查询的索引。

如果您的审计表仅包含一个包含主记录状态的字段,这可能是另一个版本。

create table audit ([status] nvarchar(20), [user] nvarchar(20), [date] date, [claimnumber] int)
insert into audit values 
('Bill', 'User5', '2017-05-01', 001),
('Bill', 'User4', '2017-05-03', 005),
('Active', 'User2', '2017-05-05', 001),
('No Bill', 'User3', '2017-05-10', 005),
('In Progress', 'User1', '2017-05-08', 001)


SELECT * FROM (
SELECT LAG([status]) OVER (PARTITION BY [claimnumber] ORDER BY [claimnumber], [date]) as oldstatus, *
FROM audit
) AS A
WHERE [user] IN ('User1','User2','User3') AND 
      (([oldstatus]='Bill' AND [status] = 'Active')
       OR ([oldstatus]='Bill' AND [status] = 'No Bill')
       OR ([oldstatus]='Active' AND [status] = 'In Progress'))
ORDER BY [claimnumber], [date] 

结果

oldstatus   status      user    date                 claimnumber
Bill        Active      User2   05.05.2017 00:00:00  1
Active      In Progress User1   08.05.2017 00:00:00  1
Bill        No Bill     User3   10.05.2017 00:00:00  5
于 2017-07-20T19:48:32.573 回答