2017-02-16 4 views
2

私は以下の問題があります 私は2つのテーブルを持っています。最初のテーブルには01001101110のような文字列が含まれています。各数字は表2で説明したスキルを表します。 ビットフィールドを個々の名前付きカラムに展開するMySQLクエリ?

そこで最初の桁は、第二の数字は人がIDを持つスキル2

テーブルを持っていることを示している人は、ID 1とスキルを持っていないことを意味するゼロを示す1:

|-----------|-----------------------------| 
|  name  |             skillset           | 
|-----------|-----------------------------| 
|   John  | 01001101110             | 
|-----------|-----------------------------| 

表2:

|-----------|-----------------------------| 
|    id       |              skill              | 
|-----------|-----------------------------| 
|       1    | polite                         | 
|-----------|-----------------------------| 
|      2     | easy going                 | 
|-----------|-----------------------------| 

今、私は結果

で問い合わせる作成する必要があります
+6

なぜ地球上のように戻ってくるのでしょうか?データを正規化し、クエリを実行するのは簡単です。 – David

+0

私は以前に会社のために働いていたスクリプト作成者はいませんでした。しかし、私は再設計はオプションだが、私が今探しているものではないことを理解している。

+0

スキルリストは158アイテムで、2つのテーブルと照合しています。このように見えるアイデアは非常に独創的ですが、それを解決する最善の方法ではないかもしれません。すべてのクレジットを元のコーダー –

答えて

1

私はこのような多くのストーリーを見てきました。「以前のコーダーがこれを実装しましたが、今はそれに固執しています。私は会社から会社に移り、できるだけ賢明で最も保守的な方法で物事を実行し、次にすぐに彼の次の被害者の会社に移動する、ただ1人の個々のコーダーがいると想像します。

私はまた、彼らはそれぞれ1または0 を保存するために、完全なバイト(8ビット)を使用して終了するので、誰かが、varchar型でビットフィールドを実装するであろうと、それは皮肉見つける:手のひらを顔に当てる:とにかく

へあなたのタスクを解決するには、動的SQLクエリを使用する必要があります。

ピボットテーブルクエリではスキルの一覧を調べるまで列の数がわからないため、動的SQLが必要ですが、番号を知らなくてもクエリを実行することはできません列のしたがって、少なくとも2つのクエリを実行する必要があります。ここで

はテストデータです:今

create table table1 (name varchar(20), skillset varchar(200)); 

insert into table1 values ('John', '01001101110110'); 

create table table2 (id int, skill varchar(20)); 

insert into table2 values 
    (1, 'polite'), 
    (2, 'easy going'), 
    (3, 'trustworthy'), 
    (4, 'loyal'), 
    (5, 'helpful'), 
    (6, 'friendly'), 
    (7, 'courteous'), 
    (8, 'kind'), 
    (9, 'obedient'), 
    (10, 'cheerful'), 
    (11, 'thrifty'), 
    (12, 'brave'), 
    (13, 'clean'), 
    (14, 'reverent'); 

あなたのスキルテーブル内の各エントリのための選択リストで一つのフィールドを追加することによって、動的なクエリーのSQLを生成巧妙なクエリです。キーは、MySQLのGROUP_CONCAT()関数です。

select name, 
mid(skillset,1,1) as `polite`, 
mid(skillset,2,1) as `easy going`, 
mid(skillset,3,1) as `trustworthy`, 
mid(skillset,4,1) as `loyal`, 
mid(skillset,5,1) as `helpful`, 
mid(skillset,6,1) as `friendly`, 
mid(skillset,7,1) as `courteous`, 
mid(skillset,8,1) as `kind`, 
mid(skillset,9,1) as `obedient`, 
mid(skillset,10,1) as `cheerful`, 
mid(skillset,11,1) as `thrifty`, 
mid(skillset,12,1) as `brave`, 
mid(skillset,13,1) as `clean`, 
mid(skillset,14,1) as `reverent` 
from table1; 

私は念のスキル名のいずれかで、バックティックと列の別名を区切るために確認しましたが、特殊文字や空白が含まれています

select concat(
    'select name,', 
    group_concat(concat(' mid(skillset,',id,',1) as `',skill,'`')), 
    ' from table1;') as _sql 
from table2; 

上記のクエリの出力は以下のとおりです。またはSQLの予約語と競合します。

は、その後これは次のような結果がある2番目のクエリとして実行することができます:

+------+--------+------------+-------------+-------+---------+----------+-----------+------+----------+----------+---------+-------+-------+----------+ 
| name | polite | easy going | trustworthy | loyal | helpful | friendly | courteous | kind | obedient | cheerful | thrifty | brave | clean | reverent | 
+------+--------+------------+-------------+-------+---------+----------+-----------+------+----------+----------+---------+-------+-------+----------+ 
| John | 0  | 1   | 0   | 0  | 1  | 1  | 0   | 1 | 1  | 1  | 0  | 1  | 1  | 0  | 
+------+--------+------------+-------------+-------+---------+----------+-----------+------+----------+----------+---------+-------+-------+----------+ 
+1

これはまさに私が探していたものです –

0

はそれSETデータ型作りを。これにより、ビット数で最大64の事前定義されたオプションを任意に組み合わせて格納でき、文字列として読み書きすることができます。

シンプルSELECT skillset FROM tbl WHERE name = 'John'は、あなたがこのようなテーブルを設計した文字列

"easy going,helpful,friendly,kind" (etc) 

Reference

関連する問題