2

Survey_1 と呼ばれる、次のようなテーブルが 1 つあります。

================================================
|id  | token  |     1X2X1     |    1X2X2       |
=====+========+===============+================|
| 1  |   1    |    YES        | Justin Beiber  |
|----+--------+---------------+----------------|
| 2  |   1    |    YES        | Britney Spears |
|----+--------+---------------+----------------|

: 1X2X1 は、調査 ID X グループ ID X 質問 ID を表します

survey_questions という別のテーブルがあります。

===============================================================
|sid |   gid  |   qid  |             question                 |
=====+========+===============+===============================|
| 1  |  2     |    1   |  Do you listen to music?             |
|----+--------+-----------------------------------------------|
| 1  |  2     |    2   |  Who is your favorite music artists? |
|----+--------+-----------------------------------------------|

sid (survey-id)、gid (group-id)、および qid (question-id) は、この表の特定の質問を定義します

次のような結果が得られるクエリが必要です。

======================================================
|           Question                  |   Answer     |
=========+===========+===============================|
| Do you listen to music?             |    YES       |            
|----------------------------------------------------|
| Who is your favorite music artists? | Justin Beiber| 
|----------------------------------------------------|

: 私のデータベースにはこれらの列が何千も含まれているため、すべてのアンケートを編集してこの形式に完全に一致させるには非常に時間がかかります。

誰でもこれを手伝ってもらえますか?ありがとうございました

4

3 に答える 3

4

テーブル スキーマを変更できますか? 最初のテーブル、survey_1 は、回答ごとに 1 つの行を使用し、行ごとに他のテーブルのキー全体を使用する方が適切です。このように(独自のインデックスを追加してください)

create table survey_1 (
  id int,
  token int,
  sid int,
  gid int,
  qid int,
  answer varchar(255)
)

データよりも

------------------------------------------
| 1 | 1 | 1 | 2 | 1 | "YES"              |
| 1 | 1 | 1 | 2 | 2 | "Justin Beiber"    |
| 2 | 1 | 1 | 2 | 1 | "YES"              |
| 2 | 1 | 1 | 2 | 2 | "Britney Spears"   |
------------------------------------------

作業がはるかに簡単になり、一般的にはより優れた設計になります。

これがどのように見えるかですhttp://sqlfiddle.com/#!2/4f1ca/2

于 2012-10-18T19:26:35.383 に答える
2

調査ごとにビューを作成します。古い調査の場合は、単純なスクリプトで実行できるはずです。新しい調査の場合は、新しい調査を作成するプロセスの一部になります。これは、viewがsurvey_1を探す方法です

create or replace view v_survey_1 as
select id, question, 1X2X1 as answer 
  from question
  join survey_1 s
 where sid = 1
   and gid = 2
   and qid = 1
union
select id, question, 1X2X2 
  from question
  join survey_1 s
 where sid = 1
   and gid = 2
   and qid = 2
;

http://sqlfiddle.com/#!2/63aee/1

ビューを構築するには、スクリプトは大まかに次のようにします。

を実行して、ビューを構築するすべてのテーブルを見つけます

select table_name 
 from information_schema.tables 
where table_schema = 'test' 
  and table_name like 'survey\_%';

ビューごとに、テーブルに対してこれを実行してユニオン パーツを見つけます。

select column_name
  from information_schema.columns 
 where table_name = 'survey_1' 
   and column_name regexp '^[0-9]+X[0-9]+X[0-9]+$';

sid、gid、qid と比較する場合は、数値部分を抽出して使用します。

このスクリプトを使用して、新しい適切なテーブルを作成することもできます。

于 2012-10-18T20:23:50.837 に答える
0

残念ながらMySQLがサポートしていない「UNPIVOT」を使用する必要があります。次のように列名をハードコーディングすることで同様のことができます(ただし、事前にすべての列を知っている必要があります)。

SELECT survey_questions.Question,
       CASE survey_questions.qid 
         WHEN 1 THEN survey_1.`1X2X1`
         WHEN 2 THEN survey_1.`1X2X2`
         WHEN 3 THEN survey_1.`1X2X3`
         WHEN 4 THEN survey_1.`1X2X4`
       // ...
       END as Answer
FROM survey_questions
JOIN survey_1 
  ON survey_questions.qid = survey_1.id
  AND survey_questions.gid = survey_1.token_id
WHERE survey_questions.sid = 1

もちろん、いつでもスクリプト言語を使用して列名を生成できます...たとえば、次のようなストアドプロシージャを作成できます。

CREATE PROCEDURE 'get_qa_for_survey'
(
  IN surveyId INT
)
BEGIN
  DECLARE query1 TEXT; 
  SET @tableName = 'survey_' + surveyId;
  SET query1 = 'SELECT survey_questions.Question,
       CASE survey_questions.qid ';

  DECLARE col_names CURSOR FOR
    SELECT column_name
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = @tableName
    AND (column_name LIKE surveyId +'X%');
    ORDER BY ordinal_position;

  select FOUND_ROWS() into num_rows;

  SET i = 1;
  the_loop: LOOP    
     IF i > num_rows THEN
        CLOSE col_names;
        LEAVE the_loop;
     END IF;

     FETCH col_names 
     INTO col_name;     
     SET query1 = query1 + ' WHEN ' + i + ' THEN ' + @tableName + '.' + col_name
     SET i = i + 1;  
  END LOOP the_loop;

  SET query1 = query1 + ' END as Answer
    FROM survey_questions
    JOIN ' + @tableName + '
      ON survey_questions.qid = ' + @tableName + '.id
      AND survey_questions.gid = ' + @tableName + '.token_id
    WHERE survey_questions.sid = ' + surveyId; 


  SET @Sql = query1;        
  PREPARE STMT FROM @Sql; 
  EXECUTE STMT; 
  DEALLOCATE PREPARE STMT;
END
于 2012-10-18T19:23:47.930 に答える