You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL自连接查询问题:求两类工单状态首次设置的时间差

工单状态首次设置时间差计算的SQL问题解决

问题描述

需要计算工单首次设置HD05/SD05/HD04状态的时间,与首次设置HD10/SD10状态的时间差。表中状态可重复设置,必须取首次出现的时间。当前使用自连接查询时:

  • 不对HD10/SD10取最小时间会返回重复结果;
  • 添加子查询限制HD10/SD10取最小时间时,无结果返回。

表结构示例

Ticket_NummerStatusDatum
HD22-26543HD042022-09-14 16:29:58.480
HD22-26543HD042022-09-14 16:29:59.480
HD22-26543HD102022-09-15 07:08:21.777
HD22-26543HD102022-09-28 15:12:09.200

原有问题SQL

当前使用的自连接查询:

SELECT DATEDIFF(MINUTE, FTa.Date, FTb.Date) AS Difference,FTa.Date,FTb.Date
FROM [dbo].[FT] FTa
INNER JOIN [dbo].[FT] FTb
ON FTa.Ticket_No = FTb.Ticket_No
WHERE FTa.Date IN (
    SELECT min(x.Date)
    FROM FT x
    WHERE x.Ticket_No = FTa.Ticket_No AND FTa.Status in ('HD04','HD05','SD05')
    ) 
AND FTb.Status IN ('HD10','SD10') AND DATEDIFF(MINUTE,FTa.Date, FTb.Date)>30

添加以下子查询限制FTb取最小时间时无结果:

SELECT min(x.Date)
FROM FT x
WHERE x.Ticket_No = FTb.Ticket_No AND FTb.Status IN ('HD10','SD10')

问题原因

添加的子查询逻辑错误:子查询中错误使用外部表FTb的Status作为过滤条件,而非子查询表x的Status。这导致子查询无法正确筛选出HD10/SD10的首次时间。

解决方案

方案1:使用CTE预聚合首次时间(推荐)

先通过CTE分别计算每个工单的两类状态首次时间,再关联计算差值,避免自连接的重复问题:

WITH FirstStatusTimes AS (
    SELECT 
        Ticket_Nummer,
        MIN(CASE WHEN Status IN ('HD04','HD05','SD05') THEN Datum END) AS First_Early_Status,
        MIN(CASE WHEN Status IN ('HD10','SD10') THEN Datum END) AS First_Late_Status
    FROM [dbo].[FT]
    GROUP BY Ticket_Nummer
)
SELECT 
    Ticket_Nummer,
    DATEDIFF(MINUTE, First_Early_Status, First_Late_Status) AS Time_Difference_Minutes,
    First_Early_Status,
    First_Late_Status
FROM FirstStatusTimes
WHERE 
    First_Early_Status IS NOT NULL 
    AND First_Late_Status IS NOT NULL
    AND DATEDIFF(MINUTE, First_Early_Status, First_Late_Status) > 30;

方案2:子查询预聚合后自连接

分别通过子查询获取两类状态的首次时间,再进行连接:

SELECT 
    DATEDIFF(MINUTE, FTa.First_Early, FTb.First_Late) AS Difference,
    FTa.First_Early,
    FTb.First_Late
FROM (
    SELECT Ticket_Nummer, MIN(Datum) AS First_Early
    FROM [dbo].[FT]
    WHERE Status IN ('HD04','HD05','SD05')
    GROUP BY Ticket_Nummer
) FTa
INNER JOIN (
    SELECT Ticket_Nummer, MIN(Datum) AS First_Late
    FROM [dbo].[FT]
    WHERE Status IN ('HD10','SD10')
    GROUP BY Ticket_Nummer
) FTb ON FTa.Ticket_Nummer = FTb.Ticket_Nummer
WHERE DATEDIFF(MINUTE, FTa.First_Early, FTb.First_Late) > 30;

这两种方案都能准确获取每个工单的两类状态首次时间,避免重复结果或无结果的问题。

内容的提问来源于stack exchange,提问作者klueting

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:05:24