应用不同的逻辑来查询数据库表并用扩展信息表示它

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

我下面有一个数据库表,我想从中编写一个 sql 查询来提取下面所需的输出。

产品

ProductID  RecordID ProductVersion  ReceivedDate         UrgencyLevel Resolved InvestigationDate    ResolvedDate            
1          17       1               2001-09-11 17:05:00  NULL         0        NULL                 NULL                
1          17       10              2001-09-11 17:05:00  6            1        2001-09-11 17:59:00  2001-09-11 20:04:00
2          13       1               2001-12-04 09:05:00  6            0        NULL                 NULL                    
2          13       11              2001-12-04 09:05:00  5            1        2001-12-04 10:19:00  2001-12-04 12:07:00
3          71       1               2001-06-08 12:36:00  5            0        2001-06-08 12:36:00  NULL    
3          71       6               2001-06-08 12:36:00  1            1        2001-06-08 12:36:00  2001-06-08 13:21:00
4          10       1               2001-05-01 11:00:00  1            0        2001-05-01 12:00:00  2001-05-01 12:30:00 
4          10       3               2001-05-01 11:00:00  1            1        2001-05-01 12:15:00  NULL
5          21       1               2001-07-23 09:00:00  8            0        2001-07-23 10:15:00  NULL    
5          21       15              2001-07-23 09:00:00  NULL         0        2001-05-23 10:30:00  NULL

每个 ProductID 都有一个 ProductVersion = 1(最低版本)和第二个 ProductVersion (最高版本)。对于每个唯一的ProductID,ReceivedDate 始终相同。此外,ReceivedDate永远不会为NULL,但ResolvedDate可以为NULL。

DurationInMinutes 在最大版本上计算为

ReceivedDate - ResolvedDate
。如果最大 ProductVersion 上的 ResolvedDate 为 NULL,则使用最小 ProductVersion 上的 ResolvedDate,否则将 NULL 分配给 DurationInMinutesResolved 列在最低版本上通常为 0,在最高版本上为 1,但在某些情况下(例如,对于 ProductID 5),我们可能在两个产品版本上都具有 0 值。在这种情况下,我们希望将最大版本上的Resolved值强制为1而不是0。

期望的输出

ProductID RecordID ReceivedDate         FirstUrgencyLevel FinalUrgencyLevel FirstInvestigationDate FinalInvestigationDate DurationInMinutes
1         17       2021-09-11 17:05:00  NULL              6                 NULL                   2001-09-11 17:59:00    179
2         13       2001-12-04 09:05:00  6                 5                 NULL                   2001-12-04 10:19:00    182       
3         71       2001-06-08 12:36:00  5                 1                 2001-06-08 12:36:00    2001-06-08 12:36:00    45    
4         10       2001-05-01 11:00:00  1                 1                 2001-05-01 12:00:00    2001-05-01 12:15:00    90
5         21       2001-07-23 09:00:00  8                 NULL              2001-07-23 10:15:00    2001-07-23 10:30:00    NULL

我已经尝试了以下方法,但似乎没有得到所需的输出。此外,我如何结合上述不同的逻辑来获得我想要的输出。

select 
ProductID,
RecordID,
ReceivedDate,
case when UrgencyLevel = 0 then UrgencyLevel end as FirstUrgencyLevel,
case when UrgencyLevel = 1 then UrgencyLevel end as FinalUrgencyLevel,
case when UrgencyLevel = 0 then InvestigationDate end as FirstInvestigationDate,
case when UrgencyLevel = 1 then InvestigationDate end as FinalInvestigationDate,
datediff(minute,ReceivedDate, ResolvedDate) as DurationInMinutes
from PRODUCT
sql-server database logic
1个回答
0
投票

你可以

  1. 使用
    MAX(ProductVersion) OVER(PARTITION BY ProductID, RecordID)
    窗口函数 识别每组输入行的最后一个
    ProductVersion
    。这可以包装在 CTE(公共表表达式)中。
  2. 使用
    CROSS APPLY
    将第一行标记为
    ProductVersion = 1
    ,最后一行定义为
    ProductVersion = MaxProductVersion
  3. 从那里,您可以按 ProductID 和 RecordID 进行分组,并使用 条件聚合 选择最终结果。 条件聚合是一种使用聚合函数(如
    COUNT()
    SUM()
    MAX()
    )以及条件
    CASE
    表达式或
    IIF()
    函数来选择性地在结果中包含或排除值的技术。

生成的查询类似于:

WITH ProductWIthMaxVersion AS (
    SELECT
        *,
        MAX(ProductVersion) OVER(PARTITION BY ProductID, RecordID)
            AS MaxProductVersion
    FROM Product
)
SELECT
    PM.ProductID,
    PM.RecordID,
    MAX(PM.ReceivedDate) AS ReceivedDate,
    MAX(CASE WHEN F.IsFirst = 1 THEN PM.UrgencyLevel END) AS FirstUrgencyLevel,
    MAX(CASE WHEN F.IsFinal = 1 THEN PM.UrgencyLevel END) AS FinalUrgencyLevel,
    MAX(CASE WHEN F.IsFirst = 1 THEN PM.InvestigationDate END) AS FirstInvestigationDate,
    MAX(CASE WHEN F.IsFinal = 1 THEN PM.InvestigationDate END) AS FinalInvestigationDate,
    MAX(CASE WHEN F.IsFinal = 1 THEN
        DATEDIFF(minute, PM.ReceivedDate, PM.ResolvedDate) END) AS DurationInMinutes
FROM ProductWIthMaxVersion PM
CROSS APPLY (
    SELECT
        CASE WHEN PM.ProductVersion = 1 THEN 1 ELSE 0 END AS IsFirst,
        CASE WHEN PM.ProductVersion = PM.MAXProductVersion THEN 1 ELSE 0 END AS IsFinal
) F
GROUP BY PM.ProductID, PM.RecordID
ORDER BY PM.ProductID, PM.RecordID

结果:

产品ID 记录ID 收到日期 第一紧急级别 最终紧急程度 首次调查日期 最终调查日期 持续时间(分钟)
1 17 2001-09-11 17:05:00 6 2001-09-11 17:59:00 179
2 13 2001-12-04 09:05:00 6 5 2001-12-04 10:19:00 182
3 71 2001-06-08 12:36:00 5 1 2001-06-08 12:36:00 2001-06-08 12:36:00 45
4 10 2001-05-01 11:00:00 1 1 2001-05-01 12:00:00 2001-05-01 12:15:00
5 21 2001-07-23 09:00:00 8 2001-07-23 10:15:00 2001-05-23 10:30:00

请参阅 this db<>fiddle 进行演示。

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