3

次のテーブルがあります。

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  | x@xxx.co.co  | 5112121212 |
|  2 |       8 | Financeiro | fin@y.net    | 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  | x@xxx.co.co | 5112121212 |
| Teste | Pespi Cola |    2 |       8 | Financeiro | fin@y.net   | 5012121212 |
+-------+------------+------+---------+------------+-------------+------------+

問題は、このようにクエリがのようにempresasフィールドを繰り返すことです (実際のテーブルは例よりも大きいです!)。gruponome

すべてのデータを 1 行で受け取る方法を知りたいです。結果は次のようになります。

+-------+------------+------+---------+------------+-------------+------------+-------------+------------+
| nome  | grupo      | id   | empresa | rotulo     | email1      | telefone1  | email2      | telefone2  |
+-------+------------+------+---------+------------+-------------+------------+-------------+------------+
| Teste | Pespi Cola |    1 |       8 | Principal  | x@xxx.co.co | 5112121212 | fin@y.net   | 5012121212 |
+-------+------------+------+---------+------------+-------------+------------+-------------+------------+

そして、3 番目のempresas_contatos行がある場合、クエリは ... を返しemail3ますtelefone3

GROUP_CONCAT() を使用できますが、これに対する解決策を見つけたいと思っています。

前もって感謝します!

4

2 に答える 2

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

于 2013-02-12T01:19:29.727 に答える
1

これを行う理由は何ですか?このクエリを実行した後、データをどのように使用しますか?スプレッドシートにインポートしますか、それとも他の方法で処理しますか?

データを後処理して、必要なものを実現する方が簡単な場合があります。

于 2013-02-12T01:51:12.927 に答える