首页 > 解决方案 > 在 T-SQL 中使用逻辑函数进行分组

问题描述

有没有办法使用 t-SQL 中的组来评估 OR 或 AND 逻辑函数?

DECLARE @TimeClock TABLE 
                   (
                       EName  NVARCHAR(14),
                       Time   NVARCHAR(5),
                       OnTime TINYINT
                   )
    
INSERT INTO @TimeClock VALUES ('Adam', '07:55', 1)
INSERT INTO @TimeClock VALUES ('Adam', '08:03', 0)
INSERT INTO @TimeClock VALUES ('Bob',  '07:57', 1)
INSERT INTO @TimeClock VALUES ('Bob',  '07:59', 1)
INSERT INTO @TimeClock VALUES ('Carl', '08:01', 0)
INSERT INTO @TimeClock VALUES ('Carl', '08:02', 0)

SELECT    
    EName,
    OR(OnTime) AS SometimesLate,
    AND(OnTime) AS AlwaysLate,
    NOT(OR(OnTime)) AS NeverLate
FROM 
    @TimeClock
GROUP BY 
    EName

对于一个非常简单的情况,我可以这样做:

SELECT    
    tc.EName,
    IIF(n.EName IS NOT NULL, 1, 0) AS SometimesLate,
    IIF(o.EName IS NULL, 1, 0) AS AlwaysLate,
    IIF(n.EName IS NULL, 1, 0) AS NeverLate
FROM 
    (SELECT DISTINCT EName FROM @TimeClock) tc
LEFT JOIN 
    (SELECT DISTINCT EName FROM @TimeClock WHERE OnTime = 1) o ON o.EName = tc.EName
LEFT JOIN 
    (SELECT DISTINCT EName FROM @TimeClock WHERE OnTime = 0) n ON n.EName = tc.EName

但是,如果我有很多不同的列(例如,OnTime、迟到 5 分钟、迟到 10 分钟等),就会变得非常密集。

在此处输入图像描述

标签: sqlsql-servertsqlcountpivot

解决方案


一些数据库具有布尔聚合函数(例如 Postgres),但 SQL Server 不是其中之一。

但是,这里不需要那种复杂的逻辑。我们可以使用 、 和 基本算术来模拟布尔聚合MIN()MAX()如下所示:

select    
    ename,
    1 - min(ontime) as sometimeslate,
    1 - max(ontime) as alwayslate,
    min(ontime) as neverlate
from @timeclock
group by ename

推荐阅读