2013-02-15 68 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