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

Microsoft SQL Server:如何将多组风险统计查询结果合并为单行输出

修正SQL Server语句实现一行显示风险统计

首先,你的原语句存在几个问题:一是语法不符合SQL Server规范,试图在FROM子句里直接用逗号连接两个SELECT子查询是行不通的;二是你给高、中风险写的条件完全一致,这显然不符合实际业务逻辑,我先假设了一些合理的风险划分规则,你可以根据真实需求调整。

另外,关于日期转换的部分,FORMAT(getdate(), 'yyyyMMdd')虽然直观,但在大数据量场景下性能不如CONVERT函数,我换成了更高效的写法,还把日期值存到变量里避免重复计算。

写法一:子查询作为列(直观易读)

这种方式每个风险统计是独立的子查询,逻辑清晰,适合各风险规则差异较大的场景:

SELECT
    -- 高风险:三个日期均已过期
    (SELECT COUNT(DISTINCT PatientKey) 
     FROM dbo.vw_FactReferral 
     WHERE PrescriptionDueDateKey <= CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
       AND OrderConfirmationDueDateKey <= CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
       AND NextDeliveryDueDateKey <= CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))) AS HighRisk,
    -- 中风险:前两个日期过期,第三个未过期(请根据业务调整)
    (SELECT COUNT(DISTINCT PatientKey) 
     FROM dbo.vw_FactReferral 
     WHERE PrescriptionDueDateKey <= CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
       AND OrderConfirmationDueDateKey <= CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
       AND NextDeliveryDueDateKey > CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))) AS MediumRisk,
    -- 低风险:至少一个日期未过期(请根据业务调整)
    (SELECT COUNT(DISTINCT PatientKey) 
     FROM dbo.vw_FactReferral 
     WHERE PrescriptionDueDateKey > CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
        OR OrderConfirmationDueDateKey > CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))
        OR NextDeliveryDueDateKey > CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))) AS LowRisk

写法二:CASE WHEN + 聚合(性能更优)

这种方式只需要扫描一次表,数据量大时性能更好,推荐优先使用:

-- 先定义今天的日期变量,避免重复计算
DECLARE @TodayInt INT = CONVERT(int, CONVERT(varchar(8), GETDATE(), 112))

SELECT
    -- 高风险统计
    COUNT(DISTINCT CASE 
        WHEN PrescriptionDueDateKey <= @TodayInt 
         AND OrderConfirmationDueDateKey <= @TodayInt 
         AND NextDeliveryDueDateKey <= @TodayInt THEN PatientKey 
    END) AS HighRisk,
    -- 中风险统计(请根据业务调整条件)
    COUNT(DISTINCT CASE 
        WHEN PrescriptionDueDateKey <= @TodayInt 
         AND OrderConfirmationDueDateKey <= @TodayInt 
         AND NextDeliveryDueDateKey > @TodayInt THEN PatientKey 
    END) AS MediumRisk,
    -- 低风险统计(请根据业务调整条件)
    COUNT(DISTINCT CASE 
        WHEN NOT (PrescriptionDueDateKey <= @TodayInt 
         AND OrderConfirmationDueDateKey <= @TodayInt) THEN PatientKey 
    END) AS LowRisk
FROM dbo.vw_FactReferral

关键提醒:

  • 务必根据你的实际业务规则调整每个风险对应的WHERE/CASE条件,我这里只是示例;
  • CONVERT(varchar(8), GETDATE(), 112)会生成yyyyMMdd格式的字符串,再转成int和你的日期键字段匹配,比FORMAT更高效;
  • 使用COUNT(DISTINCT PatientKey)确保每个患者只被统计一次,符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:37:41