【问题标题】:SQL query with multiple CASE statements具有多个 CASE 语句的 SQL 查询
【发布时间】:2017-10-31 08:40:51
【问题描述】:

我目前正在处理一些数据,这些数据显示了在诊所接受过某种类型手术的所有患者。此过程类别由多个代码组成,每个代码代表属于该类别的更具体的过程。诊所的质量倡议规定患者应在一定时间内接受这些程序之一;问题是他们每个人都有不同的标准,关于他们什么时候可能发生,以便计算质量目的。

让我分解一下,希望能更好地解释一下。假设我们有 3 个代码,每个代码代表一种过程。

CODE    DESCRIPTION
--------------------
1234    Basic procedure
5678    Intermediate procedure
9012    Thorough procedure

现在,每种类型的程序都有自己的时间表。基本版本必须在过去一年内完成才能计算在内。中间的可以是过去四年年的任何时间,彻底的可以是十年年的时间。因此,在 2014 年进行中间手术的患者仍将计入质量目的,而在 2009 年进行彻底手术的患者仍将计入。

我有我的基本查询:

SELECT DISTINCT
    PatientID,
    PatientAge,
    ProcedureCode,
    CodeDescription,
    ServiceDate,
    RenderingProvider,
    VisitType

FROM ServiceDetail

WHERE ProcedureCode IN ('1234','5678','9012')

(是的,过程代码存储为 varchars,因为实际数据库中的某些代码是字母数字)

现在,我希望能够使用 IF/THEN/ELSE 逻辑来做一些事情,除非我弄错了,否则这将是 SQL 中的 CASE 语句),可以查看代码类型、服务日期程序发生,并确定该程序是否出于质量目的而计数。

伪代码示例:

IF ProcedureCode = 5678
AND ServiceDate is between [GETDATE() minus 4 years] and GETDATE()
THEN Yes

对于其他两种程序类型,它们各自的时间范围会有相同的陈述。我希望查询仅在这些情况返回 true 时显示结果。

我的问题是我知道什么我需要做,但是我的 SQL 已经生锈了,我不确定 如何 去做。基本上我正在寻找有关语法的提示。

【问题讨论】:

  • 这些服务详情是否有唯一 ID?
  • @scsimon 有一个访问 ID 字段可以用于此目的,是的,虽然我没有在我的查询中包含它
  • 你需要查询ServiceDetail表对吧?它的结构是什么?
  • @gaganshera 不确定你所说的结构是什么意思...?

标签: sql sql-server sql-server-2012 case


【解决方案1】:

您实际上并不需要这种情况,它只会使您的查询变得复杂。您可以像使用 AND/OR 一样简单地做到这一点

SELECT DISTINCT
    PatientID,
    PatientAge,
    ProcedureCode,
    CodeDescription,
    ServiceDate,
    RenderingProvider,
    VisitType

FROM ServiceDetail

WHERE (ProcedureCode  = '1234' and ServiceDate Between getdate() AND DATEADD(year, -1, getdate()) OR
(ProcedureCode  = '5678' and ServiceDate Between getdate() AND DATEADD(year, -2, getdate()) ...

【讨论】:

  • 好的,是的,这看起来可能是更简单的选择。现在我似乎犯了一个很明显的错误,但是 SQL Server 的错误是如此不明确......我继续尝试你的方式,但 WHERE 子句的每个部分都在不同的行上。在我的每个 OR 下都有一个红色的波浪线。意识到我需要在每行的末尾添加一个右括号。每个 OR 上的红色波浪线消失了,但现在我在每个新括号上都有一个...
  • 你最后的查询是什么?
  • 您的每个条件都缺少和 getdate() .....between dateadd(...) and getdate()) 这就是@EJF 出现错误的原因。
  • 它与你的相同,但 WHERE 子句的每一行位于不同的行,只是为了保持一切整洁。每个 OR 语句看起来像 (ProcedureCode = ......DATEADD(year, -1, GETDATE()) 但我会在每个 OR 实例上得到语法错误,所以我在 GETDATE() 之后添加了额外的右括号,语法错误从 OR 转移到括号
  • @scsimon 啊哈!接得好。我敢打赌这就是问题所在
【解决方案2】:

怎么样

where
   (procedureCode = '1234' AND ServiceDate 
      Between DATEADD(year, -1, getdate()) and getdate())
or
   (procedureCode = '5678' AND ServiceDate 
       Between DATEADD(year, -4, getdate()) and getdate())
or
  .. etc

【讨论】:

  • 在这两种情况下都缺少第二部分...(...between dateadd(...) and getdate())
  • 没问题,但是现在您缺少每个括号的右括号。 :)
【解决方案3】:

这应该适用于你的 where 子句

WHERE 
    ProcedureCode IN ('1234','5678','9012')
    AND VisitID IN
    (select VisitID 
    from ServiceDetail 
    where ServiceDate >=
        case 
        when ProcedureCode = 1234 then dateadd(year,-1,getdate())
        when ProcedureCode = 5678 then dateadd(year,-4,getdate())
        when ProcedureCode = 9012 then dateadd(year,-10,getdate())
        end)
    and ServiceDate <= getdate()

或者,您可以为 where 子句的每种情况显式使用 OR 运算符。我给了CASE 表达式,因为您明确要求这样做。

如果你选择直接的方法来修复其他人的语法错误......

WHERE 
   (ProcedureCode = '1234' and ServiceDate Between DATEADD(year, -1, getdate()) and getdate()) 
OR
   (ProcedureCode = '5678' and ServiceDate Between DATEADD(year, -2, getdate()) and getdate())
etc...

【讨论】:

    猜你喜欢
    • 2022-06-21
    • 1970-01-01
    • 2014-09-21
    • 2023-02-21
    • 2021-06-02
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多