在SQL中进行分组时的条件逻辑

时间:2017-10-04 21:18:27

标签: sql sql-server sql-server-2014

我需要使用基于多个字段的一些条件逻辑对SQL Server 2014表中的一些记录进行分组,我不知道该怎么做。我已经创建了一个人为的例子来解释我所寻找的结果。

以下是患者程序表:

+----+-------+-----------+---------------+---------------+
| Id |  Name | Insurance | ProcedureName | ProcedureDate |
+----+-------+-----------+---------------+---------------+
|  1 |  Bob  |  Medicaid |   Blood Test  |   2017-06-01  |
+----+-------+-----------+---------------+---------------+
|  2 |  Bob  |  Medicaid |   Urinalysis  |   2017-06-03  |
+----+-------+-----------+---------------+---------------+
|  3 |  Bob  |  Self Pay |  Liver Biopsy |   2017-05-02  |
+----+-------+-----------+---------------+---------------+
|  4 |  Bob  |  Self Pay |    CAT Scan   |   2017-05-07  |
+----+-------+-----------+---------------+---------------+
|  5 | Sally |  Medicaid |   Ultrasound  |   2017-07-07  |
+----+-------+-----------+---------------+---------------+
|  6 | Sally |  Medicaid |     X-Ray     |   2017-07-12  |
+----+-------+-----------+---------------+---------------+
|  7 | Sally |  Medicaid |   Blood Test  |   2017-08-10  |
+----+-------+-----------+---------------+---------------+

我想按名称对这些记录进行分组,这样我最终只能得到两条记录。一个给Bob,一个给Sally。由于字段保险 ProcedureName ProcedureDate 包含不同的值,我意识到我需要决定在分组中使用哪些值用于这些字段。以下是规则:

  1. 如果保险不是医疗补助,则使用非医疗补助记录中的数据和最新的ProcedureDate。
  2. 如果保险全部是Medicaid,那么请使用最近的ProcedureDate行中的数据。
  3. 所以我想最终得到以下两条记录:

    +----+-------+-----------+---------------+---------------+
    | Id |  Name | Insurance | ProcedureName | ProcedureDate |
    +----+-------+-----------+---------------+---------------+
    |  4 |  Bob  |  Self Pay |  Liver Biopsy |   2017-05-02  |
    +----+-------+-----------+---------------+---------------+
    |  7 | Sally |  Medicaid |   Blood Test  |   2017-08-10  |
    +----+-------+-----------+---------------+---------------+
    

    我为这个问题创建了一个sample SqlFiddle here。我如何在GROUP BY子句中使用条件逻辑来获得我想要的答案?

2 个答案:

答案 0 :(得分:3)

这是优先级查询。在case order by row_number中使用select top 1 with ties * from tbl order by row_number() over(partition by name order by case when insurance<>'Medicaid' then 1 else 2 end, proceduredate desc) 表达式,并符合上述条件。

SELECT COUNT(DISTINCT user_id) AS listenCount, 
l.post_id AS postId 
FROM listen l  
WHERE l.post_id IN (' . $id . ') 
GROUP BY  l.post_id

答案 1 :(得分:1)

我把这个糟糕的解决方案放在一起。它无法与Vamsi Prabhala解决方案相比,但我相信它是正确的,所以我在这里发布。

select p1.*
from PatientProcedure p1
left join (select p2.name, max(p2.ProcedureDate) m from PatientProcedure p2 group by p2.name) t1 on t1.name = p1.name
left join (select p2.name, max(p2.ProcedureDate) m, count(p2.ProcedureDate) ct from PatientProcedure p2 where p2.insurance != 'Medicaid' group by p2.name) t2 on t2.name = p1.name
where 
(
  t2.ct is null and
  ProcedureDate = t1.m
) or
(
  insurance != 'Medicaid' and 
  ProcedureDate = t2.m
)

我相信这两个LEFT JOIN也可以分组,但是,也许下次:)