web-dev-qa-db-ja.com

テーブル値を列として使用する

私は3つのテーブルを持っています:

  1. -id、名前、説明を含む製品
  2. --id、nameを含む属性
  3. prod_attri_rel、-id、prod_id、attri_id、および値を含む

    1. 製品は次のようになります:
 1 | test | just a description for test
 2 | test2| just another description
  1. 属性は次のようになります。
 1 | height
 3 | length
 2 | width
 4 | power
 5 | id
  1. prod_attri_relは次のようになります。
1 | 1 | 1 | 2
2 | 1 | 2 | 25
3 | 1 | 3 | 20
4 | 2 | 1 | 2
5 | 2 | 2 | 25
6 | 2 | 3 | 20
7 | 2 | 4 | UBEC
9 | 2 | 5 | BC2212-850

https://dba.stackexchange.com/a/33307/48727 および https://stackoverflow.com/a/695860/182018 を見た後

今、私はこの結果を得たいと思います:

id | name | height | width | length | maybe other attr | so on and so forth
  1| test | 2      | 25    | 20     | ...

次のクエリを使用する場合:

SELECT p.id, p.name , par.value, a.name FROM products p 
JOIN prod_attri_rel par on p.id = par.prod_id
JOIN attributes a on par.attri_id = a.id

私は得る:

id | name | value| name
1  | test | 2    | height
1  | test | 25   | width
1  | test | 20   | length

それから私が試したとき:

SELECT p.id, p.name , group_concat( par.value ), group_concat( a.name ) FROM products p 
JOIN prod_attri_rel par on p.id = par.prod_id
JOIN attributes a on par.attri_id = a.id GROUP BY p.name

私はより良い結果を得ますが、実際にはそうではありません:

id | name | value   | name
1  | test | 25,2,20 | width,height,length

最後に私はこれを見つけました https://stackoverflow.com/a/10926106/182018 しかし、私はそれを私の問題に適応させるのに十分理解していませんでした。

別の方法を見つけたり、それを機能させたりする場合でも、この問題に関する助けをいただければ幸いです。

目的:これは、モーター、ESCのホイール、プロペラなど、RC玩具のさまざまな部品のデータベースです。すべて異なる属性を持っていますが、すべてのモーターは同じ属性を持ち、すべてのホイールは同じ属性を持っています。

3
Magic-Mouse

Michael Greenは、EAVパターンを使用してトラックに送ってくれたので、検索可能になりました。名前が付けられました。

この問題の解決策は次のとおりです。

SELECT 
    a.entity AS id,
    a.value AS title,
    b.value AS description,
    c.value AS height,
    d.value AS width,
    e.value AS length
FROM
    attributes a
        JOIN
    attributes b USING (entity)
        JOIN
    attributes c USING (entity)
        JOIN
    attributes d USING (entity)
        JOIN
    attributes e USING (entity)
WHERE
    a.attribute = 'name'
        AND b.attribute = 'description'
        AND c.attribute = 'height'
        AND d.attribute = 'length'
        AND e.attribute = 'width'
1
Magic-Mouse

クエリの出力は問題ありませんが、GROUPBYを使用してデータをピボットする必要があります。 ( SQLフィドル)

クエリ:

SELECT p.id, p.name 
  , MAX(IF(a.name='height',par.val,0)) As 'height'
  , MAX(IF(a.name='width',par.val,0)) As 'width'
  , MAX(IF(a.name='length',par.val,0)) As 'length'
FROM products p 
JOIN prod_attri_rel par on p.id = par.prod_id
JOIN attributes a on par.attri_id = a.id
GROUP BY p.id, p.name
;

出力:

id  name    height  length  width
1   test    2       20      25
2   test2   3       35      30

データ:

CREATE TABLE Products(id int, name varchar(50), info varchar(50));

INSERT INTO Products(id, name, info) VALUES
(1, 'test', 'just a description for test')
, (2, 'test2', 'just another description');

CREATE TABLE Attributes(id int, name varchar(50));
INSERT INTO Attributes(id,name) values
    (1, 'height')
    , (3, 'length')
    , (2, 'width')
    , (4, 'power')
    , (5, 'id');

CREATE TABLE prod_attri_rel(id int, prod_id int, attri_id int, val varchar(20));
INSERT INTO prod_attri_rel(id, prod_id, attri_id, val) values
    (1, 1, 1, '2')
    , (2, 1, 2, '25')
    , (3, 1, 3, '20')
    , (4, 2, 1, '3')
    , (5, 2, 2, '35')
    , (6, 2, 3, '30')
    , (7, 2, 4, 'UBEC')
    , (9, 2, 5, 'BC2212-850');
2