如何从表中获取最近一年的所有数据,而许多行可能与该年相关联

时间:2015-02-26 12:54:14

标签: mysql sql greatest-n-per-group

这是简化表:

id - company_id - report_year - code

1  - 123456     - 2013        - ASD  
2  - 123456     - 2013        - SDF  
3  - 123456     - 2012        - ASD  
4  - 123456     - 2012        - SDF 

我想获取指定company_id的最高report_year的所有代码。

所以我应该得到:

1 - 123456 - 2013 - ASD  
2 - 123456 - 2013 - SDF

但我不能硬编码WHERE year = 2013,因为对某些公司来说,最新的报告年份可能是2012年或2009年。所以我需要根据最新的年份获得数据。

到目前为止,我有这样的查询:

SELECT id, company_id, report_year, code,
FROM `my_table`
WHERE company_id= 123456

我尝试过使用group by和max()的一些混合物,但是我无法得到我需要的东西,这是我第一次遇到这样的请求,这让我感到困惑。

有什么想法吗?我正在使用mysql。

3 个答案:

答案 0 :(得分:2)

使用相关子查询查找公司的最新年份:

SELECT id, company_id, report_year, code,
FROM `my_table` t1
WHERE company_id = 123456
  AND report_year = (select max(report_year)
                     from `my_table` t2
                     where t1.company_id = t2.company_id)

答案 1 :(得分:1)

您可以使用同一个表上的联接来执行此操作,该表返回每个公司的最大年份,如下所示:

select my_table.id, my_table.company_id, my_table.report_year, my_table.code
from my_table
inner join (
    select max(report_year) as maxYear, company_id
    from my_table
    group by company_id
) maxYear ON my_table.report_year = maxYear.maxYear
    and my_table.company_id = maxYear.company_id

要将此限制为特定公司,只需添加where子句:

select my_table.id, my_table.company_id, my_table.report_year, my_table.code
from my_table
inner join (
    select max(report_year) as maxYear, company_id
    from my_table 
    where my_table.company_id= 123456
    group by company_id
) maxYear ON my_table.report_year = maxYear.maxYear
    and my_table.company_id = maxYear.company_id

答案 2 :(得分:1)

通常,反连接比使用子查询产生更好的性能:

SELECT t1.id, t1.company_id, t1.report_year, t1.code
FROM `my_table` t1
LEFT JOIN `my_table` t2
ON t2.company_id = t1.company_id AND t2.report_year > t1.report_year
WHERE t1.company_id = 123456 AND t2.report_year IS NULL

为获得最佳性能,请确保您在(company_id,report_year)上有多列索引。

您可以在SQL Antipatterns一书中阅读有关此技术的更多信息,这是我学习它的地方。