我在MySQL中有一个表,其中包含以下字段:
id, company_name, year, state
同一客户和年份有多行,以下是数据示例:
id | company_name | year | state
----------------------------------------
1 | companyA | 2008 | 1
2 | companyB | 2009 | 2
3 | companyC | 2010 | 3
4 | companyB | 2009 | 1
5 | companyC | NULL | 3
我正在尝试从此表创建一个视图,以显示每行一个公司(即GROUP BY
pubco_name),其中状态是给定年份的最高值。
以下是我要创建的视图示例:
id | cuompany_name | NULL | 2008 | 2009 | 2010
--------------------------------------------------
1 | companyA | NULL | 1 | NULL | NULL
2 | companyB | NULL | 2 | NULL | NULL
3 | companyC | 3 | NULL | NULL | 3
有比这更多的数据,但你可以看到我想要完成的任务。
我不知道如何通过pubco_name为每年和组选择最大状态。
这是我到目前为止的SQL(我认为我们需要在这里使用CASE
和/或sub-selects
):
SELECT
id,
company_name,
SUM(CASE WHEN year = 2008 THEN max(state) ELSE 0 END) AS 2008,
SUM(CASE WHEN year = 2009 THEN max(state) ELSE 0 END) AS 2009,
SUM(CASE WHEN year = 2010 THEN max(state) ELSE 0 END) AS 2010,
SUM(CASE WHEN year = 2011 THEN max(state) ELSE 0 END) AS 2011,
SUM(CASE WHEN year = 2012 THEN max(state) ELSE 0 END) AS 2012,
SUM(CASE WHEN year = 2013 THEN max(state) ELSE 0 END) AS 2013
FROM tbl
GROUP BY company_name
ORDER BY id DESC
提前感谢您的帮助和感谢。
答案 0 :(得分:1)
您需要转动表格,但mysql没有任何此类功能的转轴
因此我们需要复制其功能
<强> EDITED 强>
Select
group_concat(
DISTINCT
if(year is null,
CONCAT('max(if (year is null, state, 0)) as ''NULL'' '),
CONCAT('max(if (year=''', year, ''', state, 0)) as ''',year, ''' '))
) into @sql from tbl join (SELECT @sql:='')a;
set @sql = concat('select company_name, ', @sql, 'from tbl group by company_name;');
PREPARE stmt FROM @sql;
EXECUTE stmt;
<强>结果强>
| COMPANY_NAME | 2008 | 2009 | 2010 | NULL |
--------------------------------------------
| companyA | 1 | 0 | 0 | 0 |
| companyB | 0 | 2 | 0 | 0 |
| companyC | 0 | 0 | 3 | 3 |
有两种方法可以解决您的问题 1.为每年创建案例,这在我们处理年份时是不可能的 2.动态生成查询,以便根据需要获得适当的列。
我根据第二个解决方案给出了解决方案,我将生成查询并将其存储在@sql
变量中。在小提琴中,我在执行之前打印了@sql
的内容。
select company_name, max(if (year='2008', state, 0)) as '2008' ,max(if (year='2009', state, 0)) as '2009' ,max(if (year='2010', state, 0)) as '2010' ,max(if (year is null, state, 0)) as 'NULL' from tbl group by company_name;
有关group_concat()
的更多信息,请浏览链接
GROUP_CONCAT 和
的 USER DEFINED VARIABLE 强>
希望这会有所帮助..
答案 1 :(得分:0)
请参阅this question的答案中链接的页面。
请注意,执行此操作时,必须提前指定输出中需要的列数。
在回答下面的评论时,这里是一个简单/基本的实现,它重现了上面的结果表(除了ID列;没有意义,因为结果中的每一行都可以汇总上面的多行)输入表)
SELECT
`company_name`,
NULLIF(SUM(CASE WHEN `t3`.`year` IS NULL THEN `t3`.`state` ELSE 0 END), 0) AS `null`,
NULLIF(SUM(CASE WHEN `t3`.`year` = 2008 THEN `t3`.`state` ELSE 0 END), 0) AS `2008`,
NULLIF(SUM(CASE WHEN `t3`.`year` = 2009 THEN `t3`.`state` ELSE 0 END), 0) AS `2009`,
NULLIF(SUM(CASE WHEN `t3`.`year` = 2010 THEN `t3`.`state` ELSE 0 END), 0) AS `2010`
FROM
(
SELECT
`t1`.`id`,
`t1`.`company_name`,
`t1`.`year`,
`t1`.`state`
FROM `tbl` `t1`
WHERE `t1`.`state` = (
SELECT MAX(`state`)
FROM `tbl` `t2`
WHERE `t2`.`company_name` = `t1`.`company_name`
AND (`t2`.`year` IS NULL AND `t1`.`year` IS NULL OR `t2`.`year` = `t1`.`year`)
)
) `t3`
GROUP BY `t3`.`company_name`;
这使用嵌套查询:内部查询(带有t1
和t2
别名)查找每年和公司具有最大状态的行(除非您确定,否则将会中断这是唯一的!),而外部的t3
是枢轴。
我会对此进行彻底测试,以确保在真实数据上可以接受性能。