简体   繁体   English

如何使用SQL Server 2012窗口函数完成查询?

[英]How to use a SQL Server 2012 Window Function to accomplish my query?

Let's say I have a table of repair tickets that looks like so: 假设我有一张维修单表,如下所示:

Group   Ticket  Status
----------------------------
00798   299696  Open
21851   574587  Complete
21851   574588  Pending
21852   574589  Office
21866   574613  Test
21869   574617  Shipping
21870   574618  Repair
21871   574620  Open
32102   369151  Repair
43316   393920  Office
60669   433162  Office
65850   445815  Open
65999   446267  Complete
66215   446841  Repair
77818   473653  Complete
79691   477963  Office
82277   483787  Pending
86283   493697  Complete
86283   493698  Complete

I am trying to get a list of all tickets whose status is complete ONLY if every ticket in the group is complete. 我试图获取仅状态组中所有票证都完整的所有票证的列表。 Thus, from this data set, I would get these tickets: 因此,从该数据集中,我将获得以下票证:

446267     
473653     
493697    
493698   

I would NOT get 574587 because there is another ticket (574588) in its group (21851) that is set to pending, not complete. 我不会收到574587,因为在其组(21851)中还有另一张票证(574588)被设置为待处理,而不是完整。

I've tried variations of ROW_NUMBER() OVER (PARTITION BY GroupNumber, [Status] ORDER BY GroupNumber) as a subquery but can't wrap my head around this. 我已经尝试了ROW_NUMBER() OVER (PARTITION BY GroupNumber, [Status] ORDER BY GroupNumber)变体ROW_NUMBER() OVER (PARTITION BY GroupNumber, [Status] ORDER BY GroupNumber)作为子查询,但是ROW_NUMBER() OVER (PARTITION BY GroupNumber, [Status] ORDER BY GroupNumber)这个问题。 Maybe it can just be done with group by and a subquery? 也许可以通过group by和子查询来完成? Thanks. 谢谢。

SQL Fiddle: http://sqlfiddle.com/#!6/62ecb/2 SQL小提琴: http ://sqlfiddle.com/#!6 / 62ecb / 2

Either of these should work: 这些都应该起作用:

--get every record
select * 
from RepairTickets a
--where the status is complete
where [status] = 'Complete'
--and the status matches every...
and [status] = all 
(
    --other record's status
    select [status]
    from RepairTickets b
    --in the same group 
    where b.[Group] = a.[Group]
)

or 要么

--get all records
select * 
from RepairTickets a
--where the status is complete
where [status] = 'Complete'
--where there is not
and not exists
(
    --any record
    select top 1 1
    from RepairTickets b
    --in the same group
    where b.[Group] = a.[Group]
    --but with a different status
    and b.[Status] != a.[Status]
)

NB: in both of the above, since we know we're only looking for Complete records we could optimise by replacing some of the references to a.[Status] relating to the inner queries; 注意:在以上两种情况下,由于我们知道我们只是在寻找完整记录,因此可以通过替换与内部查询有关的a。[Status]的某些引用来优化它们; however what's above should be easier to modify, since you only need to declare the status you're interested in in one place. 但是,上面的内容应该更容易修改,因为您只需要在一个地方声明您感兴趣的状态即可。

You are over thinking it. 您想得太多了。 Window functions are not applicable to every case. 窗口功能并非在每种情况下都适用。 You can simply count the number of tickets in each group vs. the number of completed tickets: 您可以简单地计算每个组中的票证数量与已完成的票证数量:

WITH tmp AS
(
    SELECT  GroupID,
            COUNT(TicketID) AS TotalTicket,
            SUM(CASE WHEN Status = 'Complete' THEN 1 ELSE 0 END) AS CompletedTicket
    FROM    Repair
    GROUP BY GroupID
)

SELECT      Repair.TicketID
FROM        tmp
INNER JOIN  Repair  ON tmp.GroupID = Repair.GroupID
WHERE       tmp.CompletedTicket = tmp.TotalTicket

(SQL Fiddle is down at the moment so I can't post it) (SQL Fiddle目前处于关闭状态,所以我不能发布它)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM