将多行查询为一行

时间:2014-02-11 17:32:52

标签: mysql csv

最后一天,我遇到了一个要求,我已经将实体的所有配置共享给非工程团队 - 意味着,我需要一个Excel / CSV。

我的表结构类似于

id | entity_id | config_id | value | is_active

我的结果csv应该类似于:

Entity_id, config1_value, config2_value, config3_value ... 

我确实得到了输出,但没有很好的方法。我不相信我采取的方法。我的查询就像

SELECT entity_id,
group_concat(if(config_id = 1, value, "")) as config1_value,
group_concat(if(config_id = 2, value, "")) as config2_value,
group_concat(if(config_id = 3, value, "")) as config3_value,
...
FROM table_name
WHERE is_active = 1
AND config_id in (1,2,3...)
group by entity_id;

查询工作正常,因为表格的记录仍然少于100K,所以它也很快。如您所见,如果我需要添加或删除新的配置键进行报告,我必须至少更改2行。我正在运行MySQL 5.1。 什么是更好的解决方案?

2 个答案:

答案 0 :(得分:1)

您可以: http://sqlfiddle.com/#!2/b266c2/17

与你所做的完全不同。听起来像是在寻找pivot tablecrosstab report

另请参阅此答案:https://stackoverflow.com/a/8922865/3112803

但是如果你想动态地这样做,那么你不必继续添加/删除这些列max(if(config_id = 1, value, "")) as config1_value,,那么看看这篇文章'自动化数据透视表查询' - http://www.artfulsoftware.com/infotree/qrytip.php?id=523

答案 1 :(得分:0)

我怀疑问题是缺少某些实体的配置值。一种方法是为每个实体的每个配置值创建一行:

SELECT e.entity_id,
       group_concat(coalesce(t.value, '') order by c.config_id) as values
FROM (select distinct entity_id where is_active = 1 from table_name) e cross join
     (select 1 as config_id union all select 2 union all select 3
     ) c left outer join
     table_name t
     on t.entity_id = e.entity_id and t.config_id = t.config_id
WHERE t.is_active = 1
group by entity_id;

另一种方法是您所在的路径,其中每个值都在一个单独的列中。为此,请使用max()代替group_concat()

SELECT entity_id,
       max(if(config_id = 1, value, NULL)) as config1_value,
       max(if(config_id = 2, value, NULL)) as config2_value,
       max(if(config_id = 3, value, NULL)) as config3_value,
...
FROM table_name
WHERE is_active = 1
AND config_id in (1,2,3...)
group by entity_id;