如何使用条件来计算 case 语句中的配对变量

问题描述 投票:0回答:2

我正在使用一个数据集(在 SSMS 中),看起来像这样:

案例编号 状态 事件时间戳 已清除
1 订单已收到 2024-03-20 0
1 已完成 2024-03-21 0
1 已完成 2024-03-22 1
2 订单已收到 2024-03-24 0
2 已完成 2024-03-25 0
2 已完成 2024-03-26 1
2 已完成 2024-03-27 0
CREATE TABLE CaseTracking 
(
    [CaseID]    bigint,
    [State]     VARCHAR(512),
    [EventTimeStamp]    date,
    [Cleared]   bit
);

INSERT INTO CaseTracking ([CaseID], [State], EventTimeStamp, Cleared) VALUES
    ('1', 'OrderReceived', '2024-03-20', '0'),
    ('1', 'Completed', '2024-03-21', '0'),
    ('1', 'Completed', '2024-03-22', '1'),
    ('2', 'OrderReceived', '2024-03-24', '0'),
    ('2', 'Completed', '2024-03-25', '0'),
    ('2', 'Completed', '2024-03-26', '1'),
    ('2', 'Completed', '2024-03-27', '0');

SELECT * FROM CaseTracking

我想看看各州之间需要多长时间,因此我使用“group by”按州列组织表格。我希望制作一个表来评估每个状态的 MAX(EventTimeStamp),但如果 Cleared = 1 那么该值将返回 NULL。期望的结果看起来像这样。对于此数据库,状态可以被清除,并且它的记录方式与任何其他事件相同,但 Cleared = 1。如果 MAX(TimeEventStamp) 具有 Cleared = 1 值,则意味着它仍然需要完成,这就是我的原因就像 NULL 返回

案例编号 订单已收到 已完成
1 2024-03-20
2 2024-03-24 2024-03-27

我一直在玩https://dbfiddle.uk/JG38HeOH

我在 CASE 子句中尝试了 AND 条件,但遇到了一个问题,即在满足条件时,我不是返回我想要的 CaseID = 1 的 NULL,而是得到 MAX(TimeEventStamp)

SELECT CaseID 
  ,MAX(CASE WHEN State = 'OrderReceived' AND Cleared = 0 THEN EventTimeStamp 
            ELSE NULL END) AS OrderReceived
  ,MAX(CASE WHEN State = 'Completed' AND Cleared = 0 THEN EventTimeStamp 
            ELSE NULL END) AS Completed

FROM CaseTracking
GROUP BY CaseID

结果看起来像这样

案例编号 订单已收到 已完成
1 2024-03-20 2024-03-21
2 2024-03-24 2024-03-27
sql group-by conditional-statements case ssms
2个回答
0
投票

使用 CTE 查找最后一行:

WITH last_orderReceived AS (
  SELECT
    CaseID,
    MAX(EventTimeStamp) as EventTimeStamp
  FROM CaseTracking
  WHERE State = 'OrderReceived'
  GROUP BY CaseID
), last_completed AS (
  SELECT
    CaseID,
    MAX(EventTimeStamp) as EventTimeStamp
  FROM CaseTracking
  WHERE State = 'Completed'
  GROUP BY CaseID
)
SELECT
  c1.CaseID,
  CASE WHEN c1.Cleared = 0 THEN c1.EventTimeStamp END AS OrderReceived,
  CASE WHEN c2.Cleared = 0 THEN c2.EventTimeStamp END AS Completed
FROM CaseTracking c1
LEFT JOIN last_orderReceived o ON o.CaseID = c1.CaseID
  AND c1.EventTimeStamp = o.EventTimeStamp
LEFT JOIN last_completed c ON c.CaseID = c1.CaseID
LEFT JOIN CaseTracking c2 ON c2.CaseID = c1.CaseID
  AND c2.State = 'Completed'
  AND c2.EventTimeStamp = c.EventTimeStamp
WHERE c1.State = 'OrderReceived'

参见现场演示


0
投票
WITH
  sorted AS
(
  SELECT
    *,
    ROW_NUMBER()
      OVER (
        PARTITION BY CaseID
            ORDER BY EventTimeStamp DESC
      )
        AS row_id
  FROM
    CaseTracking
)
SELECT
  CaseID,
  MAX(CASE WHEN State = 'OrderReceived' AND Cleared = 0 THEN EventTimeStamp END) AS OrderReceived,
  MAX(CASE WHEN State = 'Completed'     AND Cleared = 0 THEN EventTimeStamp END) AS Completed
FROM
  sorted
WHERE
  State = 'OrderReceived'
  OR
  row_id = 1
GROUP BY
  CaseID

案例编号 订单已收到 已完成
1 2024-03-20
2 2024-03-24 2024-03-27
Warning: Null value is eliminated by an aggregate or other SET operation.

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.