1

1対多の関係を持つ2つのテーブルがあります。これがあるとしましょう。

**Table Owners**
K  Owner
1  Fred
2  Jason
3  Tonya

Table Cars

K CarBrand
1 Mitsubishi 
1 Honda
1 VW
2 Toyota
3 Ford

これを取得する代わりに:

K Owner CarBrand 
1 Fred  Mitsubishi 
1 Fred  Honda
1 Fred  VW

次のような結果でクエリを実行したいもの:

K Owner CarBrand1 CarBrand2 Carbrand3
1 Fred  Mitsubishi Honda     VW

どうすればこれを達成できますか?

4

2 に答える 2

2

実際にはそうではありませんが、これは近づいています

Select k, owner, group_concat(carbrand)
FROM owners, cars
WHERE
owner.k = cars.k
GROUP BY car brand

フォーマットして申し訳ありませんが、修正します。

于 2012-11-15T19:32:21.633 に答える
2

データを単一の列、複数の行から複数​​の列、および1人あたり1つの行に変換したいようです。これは基本的にはですPIVOTが、残念ながらMySQLには関数がないため、ステートメントPIVOTを含む集計関数を使用してこれを複製する必要があります。CASE

所有するカーブラ​​ンドの数がわかっている場合は、次のように値をハードコーディングできます。

select k, owner,
  max(case when nameRn = 'CarBrand1' then carbrand end) CarBrand1,
  max(case when nameRn = 'CarBrand2' then carbrand end) CarBrand2,
  max(case when nameRn = 'CarBrand3' then carbrand end) CarBrand3
from
(
  select k, owner, carbrand,
    concat('CarBrand', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
    @owner := `owner` as dummy
  from
  (
    select k, owner, carbrand, @rn:=@rn+1 overall_row_num
    from
    (
      select o.k, o.owner, c.carbrand
      from owners o
      inner join cars c
        on o.k = c.k
      order by carbrand
    ) oc, (SELECT @rn:=0) r
    order by k 
  ) r
) src
group by k, owner

SQL FiddlewithDemoを参照してください

ただし、値の数が不明な場合は、プリペアドステートメントを使用して、次の動的バージョンを生成できます。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when nameRn = ''',
      nameRn,
      ''' then carbrand end) AS ',
      nameRn
    )
  ) INTO @sql
FROM 
(
  select k, owner, carbrand,
    concat('CarBrand', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
    @owner := `owner` as dummy
  from
  (
    select k, owner, carbrand, @rn:=@rn+1 overall_row_num
    from
    (
      select o.k, o.owner, c.carbrand
      from owners o
      inner join cars c
        on o.k = c.k
      order by carbrand
    ) oc, (SELECT @rn:=0) r
    order by k 
  ) r
) src;


SET @sql = CONCAT('SELECT k, owner, ', @sql, ' 
                  from
                  (
                    select k, owner, carbrand,
                      concat(''CarBrand'', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
                      @owner := `owner` as dummy
                    from
                    (
                      select k, owner, carbrand, @rn:=@rn+1 overall_row_num
                      from
                      (
                        select o.k, o.owner, c.carbrand
                        from owners o
                        inner join cars c
                          on o.k = c.k
                        order by carbrand
                      ) oc, (SELECT @rn:=0) r
                      order by k 
                    ) r
                  ) src
                   GROUP BY k, owner');

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

SQL FiddlewithDemoを参照してください

結果は両方で同じになります:

| K | OWNER | CARBRAND1 | CARBRAND2 |  CARBRAND3 |
--------------------------------------------------
| 1 |  Fred |        VW |     Honda | Mitsubishi |
| 2 | Jason |    Toyota |    (null) |     (null) |
| 3 | Tonya |      Ford |    (null) |     (null) |
于 2012-11-15T19:33:07.987 に答える