1

私は次のようなスキーマを持っています:

CREATE TABLE prop_set (
      id INT UNSIGNED NOT NULL AUTO_INCREMENT,
      name varchar(255),
      PRIMARY KEY (id)
  );
CREATE TABLE users_props (
      user_id int UNSIGNED NOT NULL,
      prop_id int UNSIGNED NOT NULL,
      value text, 
      PRIMARY KEY (user_id,prop_id)
  );
CREATE TABLE user (
      id INT UNSIGNED NOT NULL AUTO_INCREMENT,
      name varchar(255),
      PRIMARY KEY (id)
  );

INSERT INTO prop_set SET name="prop1";
INSERT INTO prop_set SET name="prop2";
INSERT INTO prop_set SET name="prop3";


INSERT INTO user SET name="user1";
INSERT INTO user SET name="user2";

INSERT INTO users_props set user_id=1,prop_id=1,value="prop1 user1";
INSERT INTO users_props set user_id=1,prop_id=2,value="prop2 user1";
INSERT INTO users_props set user_id=1,prop_id=3,value="prop3 user1";

INSERT INTO users_props set user_id=2,prop_id=1,value="prop1 user2";
INSERT INTO users_props set user_id=2,prop_id=2,value="prop2 user2";
INSERT INTO users_props set user_id=2,prop_id=3,value="prop3 user2";

今、私は次のように選択を実行します:

SELECT u.name,ps.name AS prop,up.value
      FROM USER u
        JOIN users_props up ON u.id=up.user_id
        JOIN prop_set ps ON ps.id=up.prop_id;

そして出力を取得します:

|  NAME |  PROP |       VALUE |
-------------------------------
| user1 | prop1 | prop1 user1 |
| user2 | prop1 | prop1 user2 |
| user1 | prop2 | prop2 user1 |
| user2 | prop2 | prop2 user2 |
| user1 | prop3 | prop3 user1 |
| user2 | prop3 | prop3 user2 |

fiddle mysqlに次の出力を返すようにする方法はありますか?

| NAME  |   prop1     |     prop2   |    prop3    |
---------------------------------------------------
| user1 | prop1 user1 | prop2 user1 | prop3 user1 |
| user2 | prop1 user2 | prop2 user2 | prop3 user2 |

私はmysqlを探しています-唯一の解決策。

4

1 に答える 1

3

MySQLのピボットCASE構文は、次のようなステートメントで集計関数を使用します。

SELECT u.name,
  max(case when ps.name = 'prop1' then up.value else null end) Prop1,
  max(case when ps.name = 'prop2' then up.value else null end) Prop2,
  max(case when ps.name = 'prop3' then up.value else null end) Prop3
FROM user u 
JOIN users_props up 
  ON u.id=up.user_id 
JOIN prop_set ps 
  on ps.id=up.prop_id
GROUP BY u.name;

デモで SQL Fiddle を参照してください

上記は、列に転置する既知の値がある場合にうまく機能しますが、値が不明な場合は、準備されたステートメントを使用して動的 SQL を生成することを検討する必要があります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when ps.name = ''',
      name,
      ''' then up.value else null end) AS ''',
      name, ''''
    )
  ) INTO @sql
FROM  prop_set;

SET @sql = CONCAT('SELECT u.name, ', @sql, ' 
                  FROM user u 
                  JOIN users_props up 
                    ON u.id=up.user_id 
                  JOIN prop_set ps 
                    on ps.id=up.prop_id
                  GROUP BY u.name');

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

デモで SQL Fiddle を参照してください

結果は両方のバージョンで同じです:

|  NAME |       PROP1 |       PROP2 |       PROP3 |
---------------------------------------------------
| user1 | prop1 user1 | prop2 user1 | prop3 user1 |
| user2 | prop1 user2 | prop2 user2 | prop3 user2 |
于 2013-01-11T11:50:37.590 に答える