支付总额前10名按提供商汇总,按州划分-PostgreSQL

支付总额前10名按提供商汇总,按州划分-PostgreSQL,sql,postgresql,aggregate,common-table-expression,Sql,Postgresql,Aggregate,Common Table Expression,我有一个医疗保险数据数据库,包含三个表:提供者元数据医生的唯一号码、姓名、城市、州、凭证等;hcpcs元数据代码、说明,是否用于药品;提供商服务医生的唯一编号、hcpcs代码、该医生完成的服务数量、平均成本 我正在尝试按州、按提供商汇总前10名付款。然而,我遇到了一个问题:1我不知道如何按总付款进行排名,2我不知道如何汇总供应商。以下是迄今为止我收到的最好的查询: SELECT * FROM ( SELECT p.npi, p.nppes_provider_last_o

我有一个医疗保险数据数据库,包含三个表:提供者元数据医生的唯一号码、姓名、城市、州、凭证等;hcpcs元数据代码、说明,是否用于药品;提供商服务医生的唯一编号、hcpcs代码、该医生完成的服务数量、平均成本

我正在尝试按州、按提供商汇总前10名付款。然而,我遇到了一个问题:1我不知道如何按总付款进行排名,2我不知道如何汇总供应商。以下是迄今为止我收到的最好的查询:

SELECT *
FROM (
   SELECT p.npi,
          p.nppes_provider_last_org_name AS last_name, 
          p.nppes_provider_first_name AS first_name, 
          p.nppes_provider_city AS city,
          p.nppes_provider_state AS state,
          (ps.average_medicare_payment_amt * ps.line_srvc_cnt) AS total_amount,
          RANK() OVER (PARTITION BY p.nppes_provider_state ORDER BY ps.average_medicare_payment_amt desc) AS rank
   FROM provider_services ps
   JOIN provider p ON ps.npi = p.npi
) t
WHERE rank <= 10
GROUP BY t.last_name, t.npi, t.first_name, t.city, t.state, t.total_amount, t.rank
ORDER BY state ASC;

所以我的问题是1。提供商并没有将John Smith聚合为同一个唯一号码,该号码多次出现,并显示为2。我只能用平均付款金额而不是总金额来编译,所以排名真的搞砸了

考虑以下调整:

避免在GROUP BY的聚合查询中使用SELECT*。令人惊讶的是,PostgreSQL中允许此查询没有错误,但这种SELECT*的使用可能是GROUPBY中指定的所有列的简写。 在窗口函数的ORDERBY子句中使用计算表达式表示总金额。 对总金额应用聚合函数(如SUM),不要将其作为分组列。事实上,您并没有提到如何按提供者进行聚合。 基于状态的排名抛出基于不同列的聚合:提供者。现在,您似乎只想将排名用于筛选记录,而不想显示。 以下是:

按提供商计算每个州前10个付款金额的总付款金额

现在,如果这是您的意图,以下内容将实现:

按州和排名顺序显示每个州前10名付款的记录,如果提供商在州内或州之间多次排名,则可以重复这些记录


我猜您实际上希望在子查询中进行聚合,并按总金额进行排名:

SELECT t.*
FROM (SELECT p.npi,
             p.nppes_provider_last_org_name AS last_name, 
             p.nppes_provider_first_name AS first_name, 
             p.nppes_provider_state AS state,
             SUM(ps.average_medicare_payment_amt * ps.line_srvc_cnt) AS total_amount,
             RANK() OVER (PARTITION BY p.nppes_provider_state ORDER BY SUM(ps.average_medicare_payment_amt * ps.line_srvc_cnt) DESC) as rnk
      FROM provider_services ps JOIN
           provider p
           ON ps.npi = p.npi
      ) t
WHERE rnk <= 10
ORDER BY state ASC, total_amount DESC;

你应该展示你想要的结果。你的问题不是很清楚。
SELECT t.npi, t.last_name, t.first_name, t.city, t.state,
       SUM(t.total_amount) AS total_amount
FROM (
   SELECT p.npi,
          p.nppes_provider_last_org_name AS last_name, 
          p.nppes_provider_first_name AS first_name, 
          p.nppes_provider_city AS city,
          p.nppes_provider_state AS state,
          (ps.average_medicare_payment_amt * ps.line_srvc_cnt) AS total_amount,
          RANK() OVER (PARTITION BY p.nppes_provider_state 
                       ORDER BY ps.average_medicare_payment_amt * ps.line_srvc_cnt DESC) AS rank
   FROM provider_services ps
   JOIN provider p ON ps.npi = p.npi
) t
WHERE rank <= 10
GROUP BY t.npi, t.last_name, t.first_name, t.city, t.state
ORDER BY t.state ASC;
SELECT t.*
FROM (
   SELECT p.npi,
          p.nppes_provider_last_org_name AS last_name, 
          p.nppes_provider_first_name AS first_name, 
          p.nppes_provider_city AS city,
          p.nppes_provider_state AS state,
          (ps.average_medicare_payment_amt * ps.line_srvc_cnt) AS total_amount,
          RANK() OVER (PARTITION BY p.nppes_provider_state 
                       ORDER BY ps.average_medicare_payment_amt * ps.line_srvc_cnt DESC) AS rank
   FROM provider_services ps
   JOIN provider p ON ps.npi = p.npi
) t
WHERE rank <= 10
ORDER BY t.state, t.rank;
SELECT t.*
FROM (SELECT p.npi,
             p.nppes_provider_last_org_name AS last_name, 
             p.nppes_provider_first_name AS first_name, 
             p.nppes_provider_state AS state,
             SUM(ps.average_medicare_payment_amt * ps.line_srvc_cnt) AS total_amount,
             RANK() OVER (PARTITION BY p.nppes_provider_state ORDER BY SUM(ps.average_medicare_payment_amt * ps.line_srvc_cnt) DESC) as rnk
      FROM provider_services ps JOIN
           provider p
           ON ps.npi = p.npi
      ) t
WHERE rnk <= 10
ORDER BY state ASC, total_amount DESC;