如何在MySQL中的GROUP BY语句中选择MAX(值)

时间:2013-04-07 16:53:17

标签: mysql group-by pivot aggregate-functions

背景

我正在使用CASE表达式对2010年,2011年和2012年的数据进行转换,并按公司进行分组。正在转动/返回的“度量”是每个案例/年的max(state),并且它运作良好。

问题

我正在尝试从每个max(invoice_date)的所有记录中获取最新记录company_name,但查询仅返回满足date表达式的CASE而不是max(invoice_date)

以下是表格数据的示例:

company_name  |  invoice_date | year      |  state
--------------------------------------------------------
CompanyA      |  20130101     | 2012      |   1
CompanyA      |  20130101     | 2012      |   3
CompanyB      |  20130102     | 2012      |   2
CompanyA      |  20120103     | 2011      |   3
CompanyB      |  20120104     | 2011      |   1
CompanyB      |  20120104     | 2011      |   3
CompanyA      |  20110101     | 2010      |   4
CompanyB      |  20110105     | 2010      |   2

以下是所需视图的示例:

company_name  |  invoice_date |  2010   |   2011   |  2012
--------------------------------------------------------------
CompanyA      |  20130101     |   4     |    3     |   3 
CompanyB      |  20130102     |   2     |    3     |   2 

以下是我得到的结果示例:

company_name  |  invoice_date |  2010   |   2011   |  2012
--------------------------------------------------------------
CompanyA      |  20110101     |   4     |    3     |   3 
CompanyB      |  20110105     |   2     |    3     |   2 

请注意,2011年的date适用于CompanyA和CompanyB,这不是这两家公司表格中的最新日期。我想获得max(invoice_date)

解决:

select
company_name AS company_name,
max(invoice_date) AS invoice_date,
max((case when (year = 2010) then state else 0 end)) AS `2010`,
max((case when (year = 2011) then state else 0 end)) AS `2011`,
max((case when (year = 2012) then state else 0 end)) AS `2012`,
from tbl
group by company_name 
order by invoice_date desc

2 个答案:

答案 0 :(得分:0)

如果我是你,我会使用这样的准备好的声明,以便动态地获取所有这些年份。这样,当2013数据显示时,您不必更改查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT CONCAT(
    'MAX((CASE WHEN (year = \'',
    year,
    '\') THEN state ELSE 0 END)) AS \''
    year,
    '\''
  )
) INTO @sql
FROM tbl;

SET @sql = CONCAT('SELECT
  company_name AS company_name,
  MAX(invoice_date) AS invoice_date,', @sql, '
  FROM tbl
  GROUP BY company_name 
  ORDER BY invoice_date desc');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

答案 1 :(得分:0)

我会像这样重写你的查询:

select company_name AS company_name,
  max(invoice_date) AS invoice_date,
  sum(year = 2010) AS `2010`,
  sum(year = 2011) AS `2011`,
  sum(year = 2012) AS `2012`
from tbl
group by company_name 
order by invoice_date desc

特别是有趣的案例陈述可以缩短很多。