0

次のテーブルがあります

表 1 表 2
id q_id コンテンツ id w_id q_id c_id ランキング
---------------------- -------------------------------- --------------------
95 2046 1=E 123 22404 2046 100 1

96 2046 2=G 124 22404 2046 101 2

97 2046 3=N 125 22404 2046 102 2

98 2046 4=B 126 22404 2046 103 2

99 2046 5=V 127 22404 2046 104 3

100 2046 A1 128 22404 2046 105 3

101 2046 A2

102 2046 A3

103 2046 A4

104 2046 A5

105 2046 A6

テーブルの行から列に変換する必要があります

元の結果:

 
c_id コンテンツ EGNBV
----------------------------------------------
100 A1 1 0 0 0 0

101 A2 0 1 0 0 0

102 A3 0 1 0 0 0

103 A4 0 1 0 0 0

104 A5 0 0 1 0 0

105 A6 0 0 1 0 0

結果 1 のコード:

(SELECT c.id, c.content, a.E, a.G, a.N, a.B, a.V FROM table_1 t
INNER JOIN 
(SELECT t1.id,  
  Count(IF(t2.ranking=1,1,0)) AS E,
  Count(IF(t2.ranking=2,1,0)) AS G,
  Count(IF(t2.ranking=3,1,0)) AS N,
  Count(IF(t2.ranking=4,1,0))AS B,
  Count(IF(t2.ranking=5,1,0)) AS V
FROM table_1 t1, table_2 t2 
WHERE t1.question_id = 2046 AND t2.question_id = 2046 AND t2.choice_id = t1.id 
AND t2.ranking >= 0 AND t2.w_id IN (22404)
GROUP BY t1.id) a ON a.id = t1.id);

新しい結果へ:

内容 A1 A2 A3 A4 A5 A6
-----------------------------------------------
1=E 1 0 0 0 0 0

2=G 0 1 1 1 0 0

3=N 0 0 0 0 1 1

4=B 0 0 0 0 0 0

5=V 0 0 0 0 0 0

MySql を使用していますが、ピボットを使用できません。また、私はノーを知らないと思います。表1の「A」は「A30」まで可能です。したがって、それは動的でなければなりません.....結果2について誰かアドバイスをもらえますか?


@bluefeet左結合がtable_1の大量のデータを結合する可能性があるため、where caluseにさらに2つの条件を追加する必要があると思います。そのため、結果を表示できません。

select c.content,
sum(case when t1.content = 'A1' then 1 else 0 end) A1,
sum(case when t1.content = 'A2' then 1 else 0 end) A2,
sum(case when t1.content = 'A3' then 1 else 0 end) A3,
sum(case when t1.content = 'A4' then 1 else 0 end) A4,
sum(case when t1.content = 'A5' then 1 else 0 end) A5
from table_1 c
left join table_2 t2
on left(c.content, 1) = t2.ranking
left join table_1 t1
on t2.c_id = t1.id
where locate('=', c.content) > 0 and c.id IN (95,96,97,98,99) and w_id = 22404
group by  c.content;

結果はこのようになります

| CONTENT | A1 | A2 | A3 | A4 | A5 | A6 |
-----------------------------------------
|     1=E |  1 |  0 |  0 |  0 |  0 |  0 |
|     2=G |  0 |  1 |  1 |  1 |  0 |  0 |
|     3=N |  0 |  0 |  0 |  0 |  1 |  1 |

2 つの行が欠落しています (4=B 、5=V)。

どうすれば解決できますか?

4

1 に答える 1

0

次のクエリで結果が得られるはずですが、いくつかの仮定があります。

  • 最後のcontent列には常に等号が表示され=ます。これは、コンテンツ内の行を見つけるために使用されています。
  • 記号の付いた列の値には、最初の文字として関連付けられたランクがありますcontent=この文字は、行をランキングに結合するために使用されますtable_2

既知の数の値がある場合は、次を使用できます。

select c.content,
  sum(case when t1.content = 'A1' then 1 else 0 end) A1,
  sum(case when t1.content = 'A2' then 1 else 0 end) A2,
  sum(case when t1.content = 'A3' then 1 else 0 end) A3,
  sum(case when t1.content = 'A4' then 1 else 0 end) A4,
  sum(case when t1.content = 'A5' then 1 else 0 end) A5
from table_1 c
left join table_2 t2
  on left(c.content, 1) = t2.ranking
left join table_1 t1
  on t2.c_id = t1.id
where locate('=', c.content) > 0
group by  c.content;

SQL Fiddle with Demoを参照してください。

値の数が不明なA場合は、準備済みステートメントを使用して動的 SQL を生成できます。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'sum(CASE WHEN t1.content = ''',
      content,
      ''' THEN 1 else 0 END) AS `',
      content, '`'
    )
  ) INTO @sql
FROM Table_1
where locate('=', content)= 0;

SET @sql 
  = CONCAT('SELECT c.content, ', @sql, ' 
            from table_1 c
            left join table_2 t2
              on left(c.content, 1) = t2.ranking
            left join table_1 t1
              on t2.c_id = t1.id
            where locate(''='', c.content) > 0
            group by  c.content;');

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

SQL Fiddle with Demoを参照してください。両方とも結果が得られます。

| CONTENT | A1 | A2 | A3 | A4 | A5 | A6 |
-----------------------------------------
|     1=E |  1 |  0 |  0 |  0 |  0 |  0 |
|     2=G |  0 |  1 |  1 |  1 |  0 |  0 |
|     3=N |  0 |  0 |  0 |  0 |  1 |  1 |
|     4=B |  0 |  0 |  0 |  0 |  0 |  0 |
|     5=V |  0 |  0 |  0 |  0 |  0 |  0 |
于 2013-04-05T14:23:40.040 に答える