我说TABLE Audit
COLUMN ID, STATUS, TIME
,示例数据如下:
1. {ID = 1, STATUS = 'APPROVE', TIME = '2015-02-01'}
2. {ID = 1, STATUS = 'DECLINE', TIME = '2014-12-01'}
3. {ID = 1, STATUS = 'CLOSED', TIME = '2015-11-01'}
4. {ID = 2, STATUS = 'APPROVE', TIME = '2015-02-01'}
5. {ID = 3, STATUS = 'DECLINE', TIME = '2015-10-01'}
6. {ID = 4, STATUS = 'CLOSED', TIME = '2015-02-01'}
有一个条件:如果status='approve'
然后忽略status='decline'
,则选择所有内容。
我是否知道如何构建查询以便只获取记录:1,3,4,5,6?
我目前的方式是首先使用status='approve' and 'closed'
检索所有数据并将其存储到temptable
,然后将status = 'decline' and ID not in @temptable
的数据存储到@temptable
。然后最终select * from @temptable
。
我想知道是否还有其他方法来处理这种情况?
答案 0 :(得分:4)
您可以使用窗口函数:
WITH cte AS
(
SELECT *
,[dec] = COUNT(CASE WHEN STATUS = 'DECLINE' THEN 1 END) OVER (PARTITION BY ID)
,[app] = COUNT(CASE WHEN STATUS = 'APPROVE' THEN 1 END) OVER (PARTITION BY ID)
FROM #Audit
)
SELECT ID, STATUS, [TIME]
FROM cte
WHERE NOT ([dec] >= 1 AND [app] >= 1 AND [STATUS] = 'DECLINE');
的 LiveDemo
强>
您的专栏TIME
可能会产生误导,尤其是当它只保留日期时:)
答案 1 :(得分:2)
这个想法是要获得所有已经批准的,并且那些跳过被拒绝的那些。 我现在无法尝试,但它应该有效:
;WITH App (ID, app) AS
(SELECT ID, COUNT(1) FROM #Audit WHERE STATUS = 'APPROVE' GROUP BY ID UNION
SELECT ID, 0 FROM #Audit WHERE ID NOT IN (SELECT ID FROM #Audit WHERE STATUS = 'APPROVE') GROUP BY ID )
SELECT *, ISNULL(App.app, 0)
FROM #Audit LEFT OUTER JOIN App ON #Audit.ID = App.ID
WHERE ISNULL(App.app, 0) = 0 OR (App.app = 1 AND #audit.status != 'DECLINE')
答案 2 :(得分:1)
select *
from audit a1
where not exists(
select * from audit a2
where a2.status='approve' and a1.status='decline' and a2.id=a1.id
)