如何从列中为每个月对最大值进行分组SQL

如何从列中为每个月对最大值进行分组SQL,sql,postgresql,Sql,Postgresql,我写了一个查询,显示了月份、客户ID和每个客户花费的总金额。现在,我想向您展示花费最多的月份和客户。你能帮我一下吗?我不知道如何每月从所有客户那里拿到maxmoney。另外,总金额是通过乘以其他两列数量*单价得到的 我用我的代码得到这个: ------------------------------------ | month | customer id |Total money| ------------------------------------ | April | 12347

我写了一个查询,显示了月份、客户ID和每个客户花费的总金额。现在,我想向您展示花费最多的月份和客户。你能帮我一下吗?我不知道如何每月从所有客户那里拿到maxmoney。另外,总金额是通过乘以其他两列数量*单价得到的

我用我的代码得到这个:

------------------------------------
|  month | customer id |Total money|
------------------------------------
| April  |    12347    | value 1   |
------------------------------------
| April  |   12347     | value 2   |
------------------------------------
| April  |   12347     | value 3   |
------------------------------------
我想获得每个月花费最多的客户的id:

----------------------------------------
|  month |  customer id  | Total money  |
----------------------------------------
| April  | id of customer|value of money|
----------------------------------------
| May    | id of customer|value of money|
----------------------------------------
| June   | id of customer|value of money|
----------------------------------------
这是我拥有的代码:

SELECT to_char(invoicedate, 'Month') as Month_Name, customerid,
       SUM((quantity*unitprice)::numeric(15, 2)) as Total_Money
FROM public."My_OnlineRetail"
GROUP BY Month_Name, customerid
您可以从查询中创建一个CTE,并按月\名对其进行分组,以获得每月花费的最大金额。最后将此结果再次加入CTE,并获得客户id:

WITH cte AS (
  SELECT 
    to_char(invoicedate, 'Month') as Month_Name, 
    customerid,
    SUM((quantity*unitprice)::numeric(15, 2)) as Total_Money
  FROM public."My_OnlineRetail"
  GROUP BY Month_Name, customerid
)

SELECT c.Month_Name, c.customerid, g.Max_Month_Money
FROM cte c INNER JOIN (
  SELECT Month_Name, MAX(Total_Money) Max_Month_Money 
  FROM cte
  GROUP BY Month_Name
) g
ON g.Month_Name = c.Month_Name AND g.Max_Month_Money = c.Total_Money
使用with语句设置临时表,以便从中选择最终结果:

with
month_cust as (
    select
      to_char(invoicedate,'YYYY-MM') yyyymm,
      customerid,
      sum(quantity*unitprice) total_money
    from my_online_retail
    group by 
      to_char(invoicedate,'YYYY-MM'),
      customerid
)
select yyyymm, customerid, total_money
from month_cust m
where not exists (  -- where not exists a better customer that month:
         select 1 from month_cust
         where yyyymm=m.yyyymm and total_money>m.total_money
)
order by 1,2;
我还将您的“月”改为“月”,改为“YYYY-MM”,以避免将所有年份的四月加在一起。我猜您希望2018年4月与2019年4月分开。

Postgres支持distinct on,因此您可以:

SELECT DISTINCT ON (to_char(invoicedate, 'Month')) 
       to_char(invoicedate, 'Month') as Month_Name, customerid,
       SUM((quantity*unitprice)::numeric(15, 2) ) as Total_Money
FROM public."My_OnlineRetail"
GROUP BY Month_Name, customerid
ORDER BY Month_Name, Total_money DESC;
我应该注意的是,“月”是可疑的。它不考虑年份。我更喜欢date_trunc:


您可以按总金额降序订购,并获取第一行:

WITH "My_OnlineRetail_"( invoicedate, customerid, quantity, unitprice ) AS
(
 SELECT date'2018-04-10',12347, 50, 15 union all
 SELECT date'2018-05-13',12348, 60, 20 union all
 SELECT date'2018-06-23',12349, 55, 12  
), "My_OnlineRetail" AS
(
SELECT to_char(invoicedate, 'Month') as Month_Name, customerid,
       SUM((quantity*unitprice)::numeric(15, 2)) as Total_Money
  FROM "My_OnlineRetail_"
 GROUP BY Month_Name, customerid
)
SELECT *
  FROM "My_OnlineRetail"
 ORDER BY Total_Money desc 
 FETCH FIRST 1 ROWS ONLY;

month_name  customerid  total_money
May         12348       1200

请点击下面的链接来回答您的问题,并根据这些数据添加一些和预期的输出。请你的问题-不要在评论中发布代码或其他信息这很好,但我不理解这部分:`日期不同的月份',发票日期不同的月份',发票日期不同的月份'`名称不同的是什么,为什么有两个日期不同的月份',invoicedate@Aleksandar . . . .好的,谢谢,有没有办法用MAXTotal_money做到这一点?你可以先用MAX而不是SUM。我试过用MAX,但结果不同
WITH "My_OnlineRetail_"( invoicedate, customerid, quantity, unitprice ) AS
(
 SELECT date'2018-04-10',12347, 50, 15 union all
 SELECT date'2018-05-13',12348, 60, 20 union all
 SELECT date'2018-06-23',12349, 55, 12  
), "My_OnlineRetail" AS
(
SELECT to_char(invoicedate, 'Month') as Month_Name, customerid,
       SUM((quantity*unitprice)::numeric(15, 2)) as Total_Money
  FROM "My_OnlineRetail_"
 GROUP BY Month_Name, customerid
)
SELECT *
  FROM "My_OnlineRetail"
 ORDER BY Total_Money desc 
 FETCH FIRST 1 ROWS ONLY;

month_name  customerid  total_money
May         12348       1200