【问题标题】:Using logical functions on grouping in T-SQL在 T-SQL 中使用逻辑函数进行分组
【发布时间】:2021-01-08 00:28:23
【问题描述】:

有没有办法在 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 分钟等),就会变得非常密集。

【问题讨论】:

  • 旁白:使用Sign 实现可与聚合结合的逻辑有多种技巧。屏蔽位可以减少到1/0,如this 答案。对or 位使用Sign( B1 + B2 + ... )。 (And 就是 B1 * B2 * ...。)在this 答案中的 CTE 中使用了一个更可怕的算术逻辑示例。

标签: sql sql-server tsql count pivot


【解决方案1】:

一些数据库具有布尔聚合函数(如 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

【讨论】:

  • 好的,这太棒了。谢谢。
  • 另外,看看所有的可能性,我现在将 MAX(ontime) 视为有时ontime
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多