0

オブジェクトに関するスキーマレス メタ データを格納するための EAV ストレージ システムに取り組んでおり、現在、それを検索可能にする方法に取り組んでいますが、ほとんどの処理はデータベース サーバーによって行われています。

EAV の表は次のとおりです。

`entityID` - INT(11)
`entity` - VARCHAR(128)
`attribute` - VARCHAR(128)
`value` - BLOB

これは私の声明です:

SELECT 
    `entity`,
    (CASE WHEN `attribute` = 'bob' THEN `value` ELSE NULL END) `bob`,
    (CASE WHEN `attribute` = 'dean' THEN `value` ELSE NULL END) `dean`
FROM `eav`

次のような素敵な行のセットを返します(期待どおり):

+----------+------+------+
|  entity  | bob  | dean |
+----------+------+------+
| testEnt  | foo  | NULL | // attribute = bob
+----------+------+------+
| testEnt  | NULL | NULL | // another test attribute
+----------+------+------+
| testEnt  | NULL | NULL | // another test attribute
+----------+------+------+
| testEnt2 | foo  | NULL | // attribute = bob
+----------+------+------+
| testEnt2 | NULL | foo  | // attribute = dean
+----------+------+------+

しかし、アタッチGROUP BY (Entity)すると、結果は次のようになります。

+----------+------+------+
|  entity  | bob  | dean |
+----------+------+------+
| testEnt  | foo  | NULL |
+----------+------+------+
| testEnt2 | foo  | NULL |
+----------+------+------+

そのため、HAVINGその後の構文を使用すると機能しなくなります。返される結果が次のようになる方法はありますか:

+----------+------+------+
|  entity  | bob  | dean |
+----------+------+------+
| testEnt  | foo  | NULL |
+----------+------+------+
| testEnt2 | foo  | foo  |
+----------+------+------+
4

2 に答える 2

3

の唯一の問題はGROUP、レコードを作成したが、フィールドを集約していないことです。を使用してフィールドを集約して試してくださいMAX

SELECT 
    `entity`,
    MAX(CASE WHEN `attribute` = 'bob' THEN `value` ELSE NULL END) `bob`,
    MAX(CASE WHEN `attribute` = 'dean' THEN `value` ELSE NULL END) `dean`
FROM `eav`
GROUP BY `entity`
于 2012-11-15T14:38:13.963 に答える
2

とを使用して集計関数を適用しCASEますGROUP BY。値は文字列であるため、MAX()またはを使用MIN()して結果を返すことができます。

SELECT 
    `entity`,
    Max(CASE WHEN `attribute` = 'bob' THEN `value` ELSE NULL END) `bob`,
    Max(CASE WHEN `attribute` = 'dean' THEN `value` ELSE NULL END) `dean`
FROM `eav`
group by `entity`

SQL FiddlewithDemoを参照してください

返される値の数が不明な場合はattribute、プリペアドステートメントを使用して結果を取得できます。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when attribute = ''',
      attribute,
      ''' then value end) AS ',
      attribute
    )
  ) INTO @sql
FROM eav;

SET @sql = CONCAT('SELECT entity, ', @sql, ' 
                  FROM eav 
                   GROUP BY entity');

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

SQL FiddlewithDemoを参照してください

両方の結果は次のようになります。

|   ENTITY | BOB |   DEAN |
---------------------------
|  testEnt | foo | (null) |
| testEnt2 | foo |    foo |
于 2012-11-15T14:38:33.067 に答える