SQL子查询的错误计数和总计

时间:2018-08-21 09:20:00

标签: sql postgresql count subquery totals

我正在尝试创建一个SQL查询,以显示付款月份,客户全名,每月付款计数以及每月的总付款金额。我想展示前10名最高薪的客户。由于要显示前10名客户总共需要每个客户在整个月内支付的所有款项,因此我使用了子查询。

var triplets = new List<IEnumerable<Student>>();

for(int i = 0; i < (sortedStudents.Count - 2); i++)
{
   triplets.Add(sortedStudents.Skip(i).Take(3));
}

但是,计数和总计不正确,我很难找出原因。

enter image description here enter image description here

任何关于我做错事的建议都值得赞赏。 谢谢。

1 个答案:

答案 0 :(得分:2)

从计算所有客户总数的基本查询开始:

SELECT (c.first_name || ' ' || c.last_name) as fullname, 
       date_trunc('month', p.payment_date) as pay_mon,
       count(*) as month_count
       SUM(p.amount) as month_amount,
       SUM(SUM(p.amount)) OVER (PARTITION BY c.customer_id) as total_amount
FROM payment p JOIN
     customer c
     ON p.customer_id = c.customer_id
GROUP by c.customer_id, fullname, pay_mon;

(请注意,customer_id中包括GROUP BY。如果两个客户的姓名相同,这是一个好习惯。)

接下来,您可以使用dense_rank()获得前十名:

WITH cm as (
      SELECT (c.first_name || ' ' || c.last_name) as fullname, 
             date_trunc('month', p.payment_date) as pay_mon,
             count(*) as month_count
             SUM(p.amount) as month_amount,
             SUM(SUM(p.amount)) OVER (PARTITION BY c.customer_id) as total_amount
      FROM payment p JOIN
           customer c
           ON p.customer_id = c.customer_id
      GROUP by c.customer_id, fullname, pay_mon
     )
SELECT cm.*
FROM (SELECT cm.*,
             DENSE_RANK() OVER (ORDER BY total_amount DESC) as seqnum
      FROM cm
     ) cm
WHERE seqnum <= 10;

请注意,如果有联系,这将返回10个以上的客户。如果您希望准确地拥有10个客户(无论有何关系),请使用:

DENSE_RANK() OVER (ORDER BY total_amount DESC, customer_id) as seqnum