2013-02-12 71 views
3

我有以下表格:MySQL的左连接使用单行

mysql> select * from `empresas`; 
+----+-------+-----------+-------+------------+----------------+ 
| id | tipo | logotipo | nome | grupo  | cnpj   | 
+----+-------+-----------+-------+------------+----------------+ 
| 8 | Lazer | troll.jpg | Teste | Pespi Cola | 99999313412312 | 
+----+-------+-----------+-------+------------+----------------+ 

mysql> select * from `empresas_contatos`; 
+----+---------+------------+--------------+------------+ 
| id | empresa | rotulo  | email  | telefone | 
+----+---------+------------+--------------+------------+ 
| 1 |  8 | Principal | [email protected] | 5112121212 | 
| 2 |  8 | Financeiro | [email protected] | 5012121212 | 
+----+---------+------------+--------------+------------+ 

我想使用左连接两者,这样的:

mysql> select `e`.`nome`, `e`.`grupo`, `c`.* from `empresas` `e` 
    -> left join `empresas_contatos` `c` on 
    -> `c` . `empresa` = `e` . `id`; 
+-------+------------+------+---------+------------+-------------+------------+ 
| nome | grupo  | id | empresa | rotulo  | email  | telefone | 
+-------+------------+------+---------+------------+-------------+------------+ 
| Teste | Pespi Cola | 1 |  8 | Principal | [email protected] | 5112121212 | 
| Teste | Pespi Cola | 2 |  8 | Financeiro | [email protected] | 5012121212 | 
+-------+------------+------+---------+------------+-------------+------------+ 

的问题是,在这样的查询重复empresas字段,如grupo,nome(真实表格比示例更大!)。

我想知道如何在一行中接收所有数据。结果应该是类似的东西:

+-------+------------+------+---------+------------+-------------+------------+-------------+------------+ 
| nome | grupo  | id | empresa | rotulo  | email1  | telefone1 | email2  | telefone2 | 
+-------+------------+------+---------+------------+-------------+------------+-------------+------------+ 
| Teste | Pespi Cola | 1 |  8 | Principal | [email protected] | 5112121212 | [email protected] | 5012121212 | 
+-------+------------+------+---------+------------+-------------+------------+-------------+------------+ 

,如果有第三empresas_contatos行,查询将返回email3telefone3 ...

我可以使用GROUP_CONCAT(),但我很好奇为此寻找解决方案。

在此先感谢!

回答

2

你基本上试图做一个PIVOT。这里的问题是我们需要针对PIVOT的行标识符。这就是我已经引入了由你的empresa专栏组成的行号的地方。

所以像这样的东西应该可以工作,但是你需要知道潜在列的最大数量。但无论如何,这应该帮助你开始:

select g.empresa, 
    MAX(CASE WHEN rownum = 1 THEN g.email END) Email1, 
    MAX(CASE WHEN rownum = 2 THEN g.email END) Email2, 
    MAX(CASE WHEN rownum = 1 THEN g.telefone END) Phone1, 
    MAX(CASE WHEN rownum = 2 THEN g.telefone END) Phone2 
from (
    select id,empresa,email,telefone, 
     @running:=if(@previous=empresa,@running,0) + 1 as rownum, 
     @previous:=empresa 
    from empresas_contatos t 
     JOIN (SELECT @running:= 0) r 
     JOIN (SELECT @previous:= 0) s 
) g 
GROUP BY g.empresa 

这里是SQL Fiddle

顺便说一句 - 它看起来像你的rotulo列将需要相同的逻辑,因为它有重复。

这里是功能更强大的工作示例,以符合您的需求 - 我删除empresas_contatos.id,但如果你想要的话,只需添加另一个MAX CASE:

select e.nome, e.grupo, g.empresa, 
    MAX(CASE WHEN rownum = 1 THEN g.rotulo END) Rotulo1, 
    MAX(CASE WHEN rownum = 2 THEN g.rotulo END) Rotulo2, 
    MAX(CASE WHEN rownum = 1 THEN g.email END) Email1, 
    MAX(CASE WHEN rownum = 2 THEN g.email END) Email2, 
    MAX(CASE WHEN rownum = 1 THEN g.telefone END) Phone1, 
    MAX(CASE WHEN rownum = 2 THEN g.telefone END) Phone2 
from (
    select id,empresa,email,telefone,rotulo, 
     @running:=if(@previous=empresa,@running,0) + 1 as rownum, 
     @previous:=empresa 
    from empresas_contatos t 
     JOIN (SELECT @running:= 0) r 
     JOIN (SELECT @previous:= 0) s 
) g JOIN empresas e on g.empresa = e.id 
GROUP BY e.nome, e.grupo, g.empresa 

而且更Fiddle

+0

太棒了!非常感谢你!我根据你的回复做了这个:http://sqlfiddle.com/#!2/b8c4a/2 但是我不是100%满意,因为这个查询需要大量的复制和粘贴,嘿嘿。我会尽力改善您的查询以使其更“自动化”,但我真的很感谢您的回答。谢谢! – 2013-02-12 01:42:45

+0

@MatheusTavares - np,很高兴我能帮上忙。 MySQL中的数据透视表比其他RDBMS稍微困难一些。祝你好运。 – sgeddes 2013-02-12 01:45:07

1

这样做的原因是什么?运行此查询后如何使用数据?您是将其导入电子表格还是以其他方式处理它?

对数据进行后处理可能会更容易达到您想要的效果。