2017-08-01 33 views
0

我有以下表格:的Postgres获得销售顶级帐户排名

Account (id, name) 
Solution (id, name) 
Sales (solution_id, account_id, month, year, amount) 

我需要计算在一个特定时期每个帐户的每月销售:

SELECT 
    to_char(make_date(sales.year, sales.month, 1), 'YYYY-MM') AS period, 
    acc.id AS account_id, 
    acc.name AS account_name, 
    COALESCE(SUM(sales.net_sales), 0) AS amount 
FROM 
    (SELECT * 
    FROM sales 
    WHERE make_date(year, month, 1) >= FROM_DATE 
    AND make_date(year, month, 1) <= TO_DATE) sales 
    INNER JOIN account acc.id = sales.account_id 
GROUP BY sales.year, sales.month 
ORDER BY sales.year, sales.month ASC 

我现在可以计算在该范围内的总销售额:

SELECT 
    to_char(make_date(sales.year, sales.month, 1), 'YYYY-MM') AS period, 
    acc.id AS account_id, 
    acc.name AS account_name, 
    COALESCE(SUM(sales.net_sales), 0) AS amount 
FROM 
    (SELECT *, COALESCE(SUM(net_sales) OVER (PARTITION BY client_id), 0) AS total 
    FROM sales 
    WHERE make_date(year, month, 1) >= FROM_DATE 
    AND make_date(year, month, 1) <= TO_DATE) sales 
    INNER JOIN account acc.id = sales.account_id 
GROUP BY sales.year, sales.month 
ORDER BY sales.year, sales.month ASC 

有没有办法按顺序排列总销售额在选定时间段内只获取n顶级帐户?

+0

使用ROW_NUMBER()函数 – areklipno

回答

1

您的疑问有点混乱。第一个在语法上不正确。我认为你可以简化和目的是:

SELECT to_char(make_date(s.year, s.month, 1), 'YYYY-MM') AS period, 
     a.id AS account_id, a.name AS account_name, 
     COALESCE(SUM(s.net_sales), 0) AS amount, 
     SUM(SUM(s.net_sales)) OVER (PARTITION BY a.id) as total 
FROM sales s INNER JOIN 
    account a 
    ON a.id = s.account_id 
WHERE make_date(s.year, s.month, 1) >= FROM_DATE AND 
     make_date(s.year, s.month, 1) <= TO_DATE 
GROUP BY s.year, s.month, a.id, a.name 
ORDER BY s.year, s.month ASC; 

如果你想销售总额(或每月销售)的排名,那么你可以使用dense_rank()

SELECT ym.* 
FROM (SELECT to_char(make_date(s.year, s.month, 1), 'YYYY-MM') AS period, 
      a.id AS account_id, a.name AS account_name, 
      COALESCE(SUM(s.net_sales), 0) AS amount, 
      total, 
      DENSE_RANK() OVER (ORDER BY total DESC) as seqnum 
     FROM (SELECT s.*, SUM(s.net_sales) OVER (PARTITION BY client_id) as total 
      FROM sales s 
      ) s INNER JOIN 
      account a 
      ON a.id = s.account_id 
     WHERE make_date(s.year, s.month, 1) >= FROM_DATE AND 
      make_date(s.year, s.month, 1) <= TO_DATE 
     GROUP BY s.year, s.month 
    ) ym 
WHERE seqnum <= 3 
ORDER BY s.year, s.month ASC;