如何SQL查询有交易的当月最后一天?

How to SQL Query Last Day of the Month that has transaction?

我的这组数据如下:

+------+-------+-----+--------+
| Year | Month | Day | Amount |
+------+-------+-----+--------+
| 2019 |    01 |  01 |     10 |
| 2019 |    01 |  15 |     30 |
| 2019 |    01 |  29 |     40 |
| 2019 |    02 |  02 |     50 |
| 2019 |    02 |  22 |     60 |
| 2019 |    03 |  11 |     70 |
| 2019 |    03 |  31 |     80 |
+------+-------+-----+--------+

我只想查看每个月有交易的最后记录日。

我喜欢的显示结果应该是这样的:

+------+-------+--------+
| Year | Month | Amount |
+------+-------+--------+
| 2019 |    01 |     40 |
| 2019 |    02 |     60 |
| 2019 |    03 |     80 |
+------+-------+--------+

对于 YearMonth 的每个组合,您想获得最大的 DayAmount 值:

SELECT Year, Month, max(Day) as Day, max(Amount) as Amount
FROM t
GROUP BY Year, Month;

请注意,出现在 SELECT 子句中但未出现在 GROUP BY 子句中的每一列都必须聚合(此处为 max)。

也就是说,假设 Amount 对应于每天的总数,这就是您的示例所建议的。

如果您的 table 每天包含超过一个 Amount,那么您还需要总结每天的金额。我会使用类似的东西:

SELECT Year, Month, max(Day) as Day, max(Amount) as Amount
FROM (
  SELECT Year, Month, Day, sum(Amount) as Amount 
  FROM t
  GROUP BY Year, Month, Day
) as tmp
GROUP BY Year, Month;

test me(在您的示例中再添加一笔金额)

或:

SELECT Year, Month, Day, sum(Amount) as Amount
FROM (
  SELECT *, rank() over(partition by Year, Month order by Day desc) as r
  FROM t
) as tmp
WHERE r = 1
GROUP BY Year, Month, Day;

请注意,您要在此处使用 rank() 而不是 row_number(),因为您需要为领带(同一天)提供相同的排名标识符。

当然,如果你愿意,你可以将上面的任何查询包装成:

SELECT Year, Month, Amount
FROM (<query>) as q;

删除日期栏。

您可以使用行号来实现:

SELECT [Year], [Month], [Amount]
FROM (
    SELECT ROW_NUMBER() OVER(PARTITION BY CONCAT(YEAR,MONTH) ORDER BY DAY DESC) rn, *
    FROM table) t
WHERE rn = 1

一种方法是相关子查询:

select t.*
from t
where t.day = (select max(t2.day)
               from t t2
               where t2.year = t.year and t2.month = t.month
              );

另一种常用方法使用 row_number():

select t.*
from (select t.*,
             row_number() over (partition by year, month order by day desc) as seqnum
      from t
     ) t
where seqnum = 1;

select year,month,amount from(SELECT year,month,max(day),amount FROM t GROUP BY year,month);

您可以在下方使用:

SELECT ROW_NUMBER() OVER(PARTITION BY YEAR, MONTH ORDER BY DAY DESC) as rn, *
    FROM yourtable
    QUALIFY rn = 1

使用 ROW_NUMBER() 函数:

with cte_order as (select year, month, amount,row_number() over(partition by month order by day desc) as identity_row from test1)

select 年、月、金额 cte_order 其中 identity_row = 1;

使用 QUALIFY() 函数:

select year, month, amount, day, row_number() over(partition by month order by day desc) as identity_row from test1 qualify identity_row = 1;