2015-12-03 37 views
2

說我必須TABLE AuditCOLUMN 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

我想知道是否有其他方式來處理這種情況?

回答

3

您可以使用窗口功能:

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可以特別誤導當它只包含日期:)

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') 
+0

錯誤的結果集檢查https://data.stackexchange.com/stackoverflow/query/402943 – lad2025

+0

@ lad2025謝謝,最重要的原因是我不知道data.stackexchange查詢引擎的功能:) – Simone

+0

您'歡迎。 SEDE是快速演示的好工具:) – lad2025

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 
) 
+0

從audit a2中選擇1可以在某些circuntencies(大量行)下更高效。我很喜歡這個答案。 +1 –

+0

IMO在這種情況下'select 1'和'select *'之間絕對沒有性能差異 - SQL服務器無論如何都不處理/返回所有列。 – Arvo

+0

我只是提到它,因爲它可以在某些情況下提高性能,並選擇top 1通常是首選。在id爲where狀態=批准狀態的情況下,選擇1只能進行索引查找。選擇*也會跟隨一個鍵查找。 –