2012-03-09 12 views
0

2つのリスト(私の場合は要件とテストケース)の関係を格納するこのデータベーステーブル(いくつかのサンプルコード)を持っていて、テストケースとカラムを示す行を持つテーブルを作成し、関係が存在する。多対多リレーションシップを2列テーブルから変換するにはどうすればよいですか?

いくつかの制限

  • これはオープンソーステストケース管理システム(TestLinkの)に属しているように私は、DBの構造を変更する贅沢を有していません。
  • これにはいくつかのコードを書くことができますが、私はこれをMySQLで行うことができます。
  • ああ、はい、それはMySQLを使用するので、これはその環境で動作する必要があります。
  • この機能は存在していましたが、通常、この種の作業によって数万のテストケースと要件がある場合には、データベースが無駄になります。

    テーブルpivotreq_id INT(11)、 testcase_id INT(11) )を作成します。テーブルの

    /*データpivot */

    pivotreq_idtestcase_id)値(1,1)に挿入します。

    insert into pivotreq_id,testcase_id)値(2,2);

    insert into pivotreq_id,testcase_id)値(3,3);

    insert into pivotreq_id,testcase_id)値(4,1);

    insert into pivotreq_id,testcase_id)値(5,2);

    insert into pivotreq_id,testcase_id)値(6,3);

    insert into pivotreq_id,testcase_id)値(2,1);

    insert into pivotreq_id,testcase_id)値(3,2);

    私は、クエリから抜け出すためにしたいことは、このようなsomethignに見えるテーブルである

1 2 3 4 5 6 
1 x x   x 
2  x x   x 
3   x    x 

注:行testcase_idsと列が「req_ids」

されています

誰もがちょうどSQLとこれを得る方法のヒントを持っていますか?

以下
+1

リレーショナルモデルのレポートを生成しようとしていますが、これはSQLで行うべきことではありません。 SQLは、データをフォーマットするのではなく、構造化されたデータを確実に格納および返すためのエンジンです。レポートツールやスプレッドシートでも、このデータを簡単にピボットできるようになります。 – MyItchyChin

+0

既知のtestcase_idsのセットを持っているなら、退屈な一連の左結合を書いて結果を得ることができます。あなたがわからない場合は、一連の左結合を動的クエリとして生成し、それを前述の厄介なクエリにまとめます。それはいずれの方法でも退屈で不愉快です。 – Griffin

+0

テストケースは(要件のリストのように)時間とともに成長するので、これを実現する一般的な方法が好ましい方法です。 –

答えて

0

私は今、私が達成しようとしている何のために名前を持っています。それは「ダイナミックなクロス集計」です。ここで私が解決策を得た方法があります。ここに来るための明確な指示についてはhttp://rpbouman.blogspot.com/2005/10/creating-crosstabs-in-mysql.htmlに感謝します。

回線1-20 - テストに使用するテーブルを設定します。

行22-29 - 「静的な」クロス集計クエリ。私はいくつの要件があるかを知っていると仮定します。動的上記の静的なクエリを生成し、クエリ - おかげD Macが解決のために、あなたは:)

行30-44を与えました。

行45-72 - これが問題の原因です。その目的は、動的クエリの結果を返すストアドプロシージャを作成することです。 MySQLには構文上の問題があると言われていますが、修正方法はわかりません。何かご意見は?

drop table if exists pivot; 

create table `pivot` ( 
`req_id` int(11), 
`testcase_id` int(11) 
); 

/*Data for the table `pivot` */ 

insert into `pivot`(`req_id`,`testcase_id`) values (1,4); 
insert into `pivot`(`req_id`,`testcase_id`) values (2,4); 
insert into `pivot`(`req_id`,`testcase_id`) values (3,4); 
insert into `pivot`(`req_id`,`testcase_id`) values (4,7); 
insert into `pivot`(`req_id`,`testcase_id`) values (1,7); 
insert into `pivot`(`req_id`,`testcase_id`) values (2,12); 
insert into `pivot`(`req_id`,`testcase_id`) values (3,12); 
insert into `pivot`(`req_id`,`testcase_id`) values (4,4); 

select * from pivot; 

select testcase_id 
,  if(sum(req_id = 1), 1, 0) 
,  if(sum(req_id = 2), 1, 0) 
,  if(sum(req_id = 3), 1, 0) 
,  if(sum(req_id = 4), 1, 0) 
from pivot 
group by testcase_id; 

select concat(
     'select testcase_id','\n' 
     , group_concat(
     concat(
       ',  if(sum(req_id = ',p2.req_id,'), 1, 0)','\n' 
     ) 
      order by p2.req_id 
      separator '' 
     ) 
     , 'from pivot','\n' 
     , 'group by testcase_id;','\n' 
    ) statement 
from pivot p2 
order by p2.req_id; 

CREATE PROCEDURE p_coverage() 
LANGUAGE SQL 
NOT DETERMINISTIC 
CONTAINS SQL 
SQL SECURITY DEFINER 
begin 
    select concat(
        'select testcase_id','\n' 
        , group_concat(
        concat(
          ',  if(sum(req_id = ',p2.req_id,'), 1, 0)','\n' 
        ) 
         order by p2.req_id 
         separator '' 
        ) 
        , 'from pivot','\n' 
        , 'group by testcase_id;','\n' 
       ) statement 
    into @coverage_query 
    from pivot p2 
    order by p2.req_id; 

    prepare coverage from @coverage_query; 

    execute coverage; 

    deallocate prepare coverage; 
end; 

select * from pivot; 
1

多くの方が効率的である:

はtest_casesのための1つのテーブルを作成し、要件第三のテーブルマップで、その後

requirements(
id int(11) auto_increment, 
requirements varchar(200), 
primary key(id)) 

関係

ため

create table testCases(
id int(11) auto_increment, 
testcase varchar(200), 
primary key(id)) 

1つの表のように

create table matchRequirementsToTests(
requirements varchar(200), 
testcase varchar(200), 
primary key(requirements, testcase), 
foreign key (requirements) references Requirements(id), 
foreign key(test case) references Test_cases(id)) 
+0

申し訳ありませんが、このdbは変更するのではなく、照会することです。 –

+0

私は参照してください。残念ながら、あなたがやろうとしていることはmysqlにはあまり適していません。あなたは、制御層でそれを行う必要があります - php、javaなど、mysqlから結果セットを取得した後 – kasavbere

+0

こんにちは。これは3つのテーブルを(多対多の関係で)作成する方法ですが、どのようにクエリを実行するために使用しますか(そしてSQLは関係に従います)?ありがとう – skan

1
select testcase_id, 
    if(sum(req_id = 1), 'X', '') as '1', 
    if(sum(req_id = 2), 'X', '') as '2', 
    if(sum(req_id = 3), 'X', '') as '3', 
    if(sum(req_id = 4), 'X', '') as '4', 
    if(sum(req_id = 5), 'X', '') as '5', 
    if(sum(req_id = 6), 'X', '') as '6' 
from pivot 
group by testcase_id; 

それは醜いですが、それは動作します:

+-------------+---+---+---+---+---+---+ 
| testcase_id | 1 | 2 | 3 | 4 | 5 | 6 | 
+-------------+---+---+---+---+---+---+ 
|   1 | X | X | | X | | | 
|   2 | | X | X | | X | | 
|   3 | | | X | | | X | 
+-------------+---+---+---+---+---+---+ 
3 rows in set (0.00 sec) 
+0

私は要件を追加するたびに、私はスクリプトを変更する必要がありますか?これを一般化する方法はありますか? –

+0

結果セットに列を動的に生成する方法がわかりません。それが私のアプリケーションだったら、SQLを生成するプログラムを書いて、データベースにSQLを実行します。動的な部分を行うためにSQLを取得しようとしないでください。効率的なSQLを他の手続き型言語で記述するために、より多くのツールがあります。スキーマを自動的に分析し、必要な列を決定し、特定のSQLを生成し、実行し、必要な出力を得ることができます。 –

関連する問題