Sql:选择所有类型的条件为真的位置

时间:2013-02-15 17:56:26

标签: sql sql-server sql-server-2008 tsql

我有一个表定义并填充如下:

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)

我想返回不同的ProjectId,EmployeeId对以及任何警告或过期:

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)。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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)

答案 2 :(得分: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