检索每个组中的最后一条记录未获得预期结果 - MySQL

Retrieving the last record in each group not getting expected result - MySQL

我想从 table.

中获取每个类别最近两个月的数据

Table 看起来像:

ID 年 月 类别 价值
1个 2019 1个 测试1 10
2个 2018 12 测试1 10
3个 2018 10 测试1 10
4个 2018 1个 测试2 10
5个 2018 12 测试2 10
6个 2018 1个 测试3 10


预期输出:

ID 年 月 类别 价值
1个 2019 1个 测试1 10
2个 2018 12 测试1 10
5个 2018 12 测试2 10
4个 2018 1个 测试2 10
6个 2018 1个 测试3 10


我尝试使用:

SELECT a.year,a.month,a.value, a.category
FROM test_data AS a
WHERE 
(
SELECT COUNT(*)
FROM test_data AS b
WHERE b.category = a.category AND (b.year >= a.year AND b.month >= a.month)) <= 2
ORDER BY a.year DESC, a.month DESC

但它给出了TEST1类别的额外记录。我猜是因为它在年度条件下没有按预期工作。请为此提供解决方案

您的首要工作应该是修复您的数据模型并使用类似 date 的数据类型来存储日期信息,而不是将其分散在不同的列中。这应该像向 table 添加一个新列并从现有列更新它一样简单:

alter table test_data add mydate date;
update test_data set mydate = concat(year, '-', month, '-01');

就是说,要使您当前的查询有效,您需要按如下方式微调日期条件。一种选择使用算术:

SELECT a.year, a.month, a.value, a.category
FROM test_data AS a
WHERE (
    SELECT COUNT(*)
    FROM test_data AS b
    WHERE 
        b.category = a.category 
        AND 100 * b.year + b.month >= 100 * a.year + a.month
) <= 2
ORDER BY a.year DESC, a.month DESC

或者,如果您是 运行 MySQL 8.0,您可以使用 row_number():

SELECT  a.year, a.month, a.value, a.category
FROM (
    SELECT 
        a.*,
        ROW_NUMBER() OVER(PARTITION BY a.category ORDER BY a.year DESC, a.month DESC)
    FROM test_data AS a 
) a
WHERE rn <= 2