2016-04-29 61 views
0

我想创建一个查询,我不必使用GROUP BY来获取我的项目,否则他们会将数据拆分成行。这是我有,运行,但我得到相同的行patient_idlast_servicelast_payment从不出现在同一行中。我得到3行,他们似乎分裂了last_service,last_payment,以及一行都是NULL。这是我的查询:多个行相同的标识

WITH adj_rep_les AS(
SELECT DISTINCT t.clinic, t.patient_id, a.adj_desc 
FROM transactions t 
LEFT JOIN adjustments a 
    ON(t.clinic=a.clinic AND a.adjustment_id=t.adjustment_id) 
WHERE a.adj_desc LIKE '%TAB%' 
AND time_ran > '2016-03-27') 

SELECT DISTINCT 
     c.clinic_id, 
     w.patient_id, 
     p.city, 
     p.state, 
     p.zipcode, 
     SUM(t.amount) OVER (PARTITION BY w.clinic, w.patient_id) AS balance, 
     CASE WHEN t.impacts='P' THEN FIRST_VALUE(t.date_entered) OVER (PARTITION BY w.clinic, w.patient_id ORDER BY t.date_entered DESC) END AS last_service, 
     CASE WHEN t.impacts='C' THEN FIRST_VALUE(t.date_entered) OVER (PARTITION BY w.clinic, w.patient_id ORDER BY t.date_entered DESC) END AS last_payment, 
     FIRST_VALUE(s.description) OVER (PARTITION BY w.clinic, w.patient_id ORDER BY t.date_entered DESC) AS service_done 

FROM adj_rep_les w 
LEFT JOIN clinic_master c 
    ON (w.clinic=c.clinic) 
LEFT JOIN patient p 
    ON (w.clinic=p.clinic AND w.patient_id=p.patient_id) 
LEFT JOIN transactions t 
    ON (w.clinic=t.clinic AND w.patient_id=t.patient_id) 
LEFT JOIN services s 
    ON (t.clinic=s.clinic AND t.service_code=s.service_code) 

有什么想法?我还要提到CASE内的FIRST_VALUE似乎没有工作并给出相同的结果,无论如何忽略t.impacts的过滤器。在壳体内使用MAX(t.date_entered)可选择地尝试,但需要一个GROUP BY由于MAX作为一个聚合函数

示例数据结果: Sample Data

预先感谢。

+0

只是一个猜测,因为没有提供样本数据和ddl。尝试移动'CASE WHEN t.impacts ='P'THEN FIRST_VALUE(t.date_entered)OVER(PARTITION BY w.clinic,w.patient_id ORDER BY t.date_entered DESC)END as last_service, CASE WHEN t.impacts ='C 'THEN FIRST_VALUE(t.date_entered)OVER(通过w.clinic分区,w.patient_id ORDER BY t.date_entered DESC)END AS last_payment'传递给CTE并在CTE中转换它们,并在主SELECT中删除具有事务的联接。 – Serg

回答

3

其中的一些问题是:

  • 将与transactions结果在每交易记录加入,而你只需要每一个病人的记录。为了解决这个问题,你可以在子查询中选择交易,并为每个病人过滤一条记录;
  • CASE构造击败了每个病人需要一条记录的逻辑,因为你永远不可能同时拥有两个条件。相反,这些CASE结构应该出现在一些聚合中。

问题不大:

  • 您使用的地方LEFT JOIN它是清楚的是,INNER JOIN也有同样的结果。后者通常具有更好的性能,所以我建议尽可能使用它。
  • 你不使用adj_desc以外的CTE,所以不需要SELECT它;
  • 您不会将master_clinic表用于除您已具有的主键值以外的任何其他值,因此我认为您可以将该表离开;
  • 您使用列进行参照完整性,但选择clinic_id。我认为这是一个错字。

下面是该查询我建议:

WITH adj_rep_les AS (
    SELECT DISTINCT t.clinic, t.patient_id 
    FROM  transactions t 
    INNER JOIN adjustments a 
      ON t.clinic=a.clinic 
      AND a.adjustment_id=t.adjustment_id 
    WHERE  a.adj_desc LIKE '%TAB%' 
    AND  time_ran > '2016-03-27') 
SELECT DISTINCT 
      w.clinic, 
      w.patient_id, 
      p.city, 
      p.state, 
      p.zipcode, 
      x.balance, 
      x.last_service, 
      x.last_payment, 
      x.service_done 
FROM  adj_rep_les w 
INNER JOIN patient p 
     ON w.clinic=p.clinic 
     AND w.patient_id=p.patient_id 
INNER JOIN (
      SELECT  t.clinic, 
         t.patient_id, 
         SUM(t.amount) 
          OVER (PARTITION BY t.clinic, t.patient_id) AS balance, 
         MAX(CASE WHEN t.impacts='P' THEN t.date_entered END) 
          OVER (PARTITION BY t.clinic, t.patient_id) AS last_service, 
         MAX(CASE WHEN t.impacts='C' THEN t.date_entered END) 
          OVER (PARTITION BY t.clinic, t.patient_id) AS last_payment, 
         ROW_NUMBER() 
          OVER (PARTITION BY t.clinic, t.patient_id 
           ORDER BY t.date_entered DESC) AS rn, 
         s.description AS service_done 
      FROM  transactions t 
      LEFT JOIN services s 
        ON t.clinic=s.clinic 
        AND t.service_code=s.service_code) as x 
     ON w.clinic=x.clinic 
     AND w.patient_id=x.patient_id 
     AND rn = 1 

rn = 1条件可以确保得到准确地从transaction表中的一个记录,一个对于给定的患者和诊所最近date_entered

+0

@OM窒息,这是否解决您的问题?你可以提供一些反馈吗? – trincot

+0

这确实看起来像我希望的那样工作。我对SQL依然相当陌生,并且迄今为止所学的知识已经到期。我非常感谢所有对此事的帮助和见解。 –

+0

不客气。不要犹豫,发布新的问题! – trincot

相关问题