2013-02-15 78 views
2

我有一個表定義並填充爲真如下:SQL:選擇其中一個條件是所有類型

DECLARE @Temp TABLE 
(
    ProjectId INT, 
    EmployeeId INT, 
    SomeTypeId INT, 
    IsExpired BIT, 
    IsWarning BIT, 
    IsIncomplete BIT 
) 

--all incomplete... 
INSERT INTO @Temp VALUES (1, 1, 1, 0, 0, 1) 
INSERT INTO @Temp VALUES (1, 1, 2, 0, 0, 1) 
INSERT INTO @Temp VALUES (1, 1, 3, 0, 0, 1) 

--two warnings... 
INSERT INTO @Temp VALUES (1, 2, 1, 0, 1, 0) 
INSERT INTO @Temp VALUES (1, 2, 2, 0, 1, 0) 
INSERT INTO @Temp VALUES (1, 2, 3, 0, 0, 0) 

--two expirations... 
INSERT INTO @Temp VALUES (1, 3, 1, 0, 0, 0) 
INSERT INTO @Temp VALUES (1, 3, 2, 1, 0, 0) 
INSERT INTO @Temp VALUES (1, 3, 3, 1, 0, 0) 

我想返回不同的專案編號,僱員對任何警告或到期日:

SELECT DISTINCT ProjectId, EmployeeId FROM @Temp WHERE IsWarning = 1 OR IsExpired = 1 

沒問題。

但是,我想還返回ProjectId,EmployeeId對,其中IsWarning = 0和IsExpired = 0和IsIncomplete = 1,但是對於所有SomeTypeId(1,2,3),這必須爲true。換句話說,沒有警告,沒有到期,對於所有類別都只是不完整的。

SomeTypeId Fks到查找表。目前只有3個參賽作品,但未來可能會更多。

任何想法?

我希望返回ProjectId,EmployeeId(1,1)。

回答

2

這使用MAXMIN來看到所有值都是相同的;人們需要一個+ 0添加到每個位,使其可正常數值聚合函數(如MIN/MAX/SUM/...)

SELECT ProjectId, EmployeeId 
FROM Temp 
GROUP BY ProjectId, EmployeeId 
HAVING MAX(IsWarning + 0) = 0 
    AND MAX(IsExpired + 0) = 0 
    AND MIN(IsIncomplete + 0) = 1 

An SQLfiddle for testing

+0

這對於'IsWarning = 0且IsExpired = 0且IsIncomplete = 1'的所有1,2,3 SomeTypeId'記錄' – Kaf 2013-02-15 18:33:27

+0

@Kaf Hm?我很可能誤解了這個問題,但我看不出哪種情況不起作用。你能舉個反例嗎? – 2013-02-15 18:35:13

+0

很好的解決方案。謝謝。 – 2013-02-15 18:36:53

0

我不確定您的問題是否意味着您希望在SAME查詢中獲得這些結果,或者您是否需要全新的查詢。假如是後者,你的查詢將是:

SELECT DISTINCT ProjectId, EmployeeId FROM @Temp WHERE (IsWarning = 0 AND IsExpired = 0 AND IsIncomplete = 1) 

假設是前者,那就是:

SELECT DISTINCT ProjectId, EmployeeId FROM @Temp WHERE (IsWarning = 1 OR IsExpired = 1) 

OR(IsWarning = 0 AND IsExpired = 0 AND IsIncomplete = 1)

+0

嗯......不完全是。對於不完全的情況,我需要確保你的第一個查詢是真實的,但是要覆蓋由SomeTypeId定義的所有類型。 – 2013-02-15 18:34:09

0

試試這個假設你沒有重複記錄;

請注意union添加假設你還是需要選擇數據WHERE IsWarning = 1 OR IsExpired = 1。如果你不需要他們,只需刪除它。

SQL-DEMO HERE

;with cte as (
    select projectid, employeeid, 
     case when sometypeid in (1,2,3) and 
        IsWarning = 0 and IsExpired = 0 and IsIncomplete = 1 
       then 1 else 0 end x 
    from temp 
) 
select projectid, employeeid 
from cte 
group by projectId, employeeid 
having sum(x) >= 3 
union 
select projectid, employeeid 
from Temp 
where IsWarning = 1 or IsExpired = 1