1

次の形式のテーブルがあります。

mysql> describe unit_characteristics;
+----------------------+------------------+------+-----+---------+----------------+
| Field                | Type             | Null | Key | Default | Extra          |
+----------------------+------------------+------+-----+---------+----------------+
| id                   | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| uut_id               | int(10) unsigned | NO   | PRI | NULL    |                |
| uut_sn               | varchar(45)      | NO   |     | NULL    |                |
| characteristic_name  | varchar(80)      | NO   | PRI | NULL    |                |
| characteristic_value | text             | NO   |     | NULL    |                |
| creation_time        | datetime         | NO   |     | NULL    |                |
| last_modified_time   | datetime         | NO   |     | NULL    |                |
+----------------------+------------------+------+-----+---------+----------------+

各uut_snには、複数のcharacteristic_name/valueのペアがあります。MySQLを使用してテーブルを生成したい

+----------------------+-------------+-------------+-------------+--------------+
| uut_sn | char_name_1 | char_name_2 | char_name_3 | char_name_4 | ...          |
+----------------------+-------------+-------------+-------------+--------------+
| 00000  | char_val_1  | char_val_2  | char_val_3  | char_val_4  | ...          | 
| 00001  | char_val_1  | char_val_2  | char_val_3  | char_val_4  | ...          |
| 00002  | char_val_1  | char_val_2  | char_val_3  | char_val_4  | ...          |
| .....  | char_val_1  | char_val_2  | char_val_3  | char_val_4  | ...          |
+----------------------+------------------+------+-----+---------+--------------+

これはたった1つのクエリで可能ですか?

ありがとう、-peter

4

2 に答える 2

3

これは標準のピボットクエリです。

  SELECT uc.uut_sn,
         MAX(CASE 
               WHEN uc.characteristic_name = 'char_name_1' THEN uc.characteristic_value 
               ELSE NULL 
             END) AS char_name_1,
         MAX(CASE 
               WHEN uc.characteristic_name = 'char_name_2' THEN uc.characteristic_value 
               ELSE NULL 
             END) AS char_name_2,
         MAX(CASE 
               WHEN uc.characteristic_name = 'char_name_3' THEN uc.characteristic_value 
               ELSE NULL 
             END) AS char_name_3,
    FROM unit_characteristics uc
GROUP BY uc.uut_sn

動的にするには、 PreparedStatementsと呼ばれるMySQLの動的SQL構文を使用する必要があります。2つのクエリが必要です。最初のクエリは値のリストを取得するcharacteristic_nameため、私の例で最終的なクエリとして表示されているように、適切な文字列をCASE式に連結できます。

于 2010-08-18T18:24:06.147 に答える
1

EAVアンチパターンを使用しています。含める特性をハードコーディングせずに、記述したピボットテーブルを自動的に生成する方法はありません。@OMG Poniesが言及しているように、動的SQLを使用して、結果に含める一連の特性のクエリをカスタム方式で一般化する必要があります。

代わりに、データベースに格納されているため、行ごとに1つの特性をフェッチすることをお勧めします。アプリケーションオブジェクトで、すべての特性を備えた単一のUUTを表す場合は、行をフェッチするときに行をループするコードを記述します。アプリケーション、それらをオブジェクトに収集します。

たとえば、PHPの場合:

$sql = "SELECT uut_sn, characteristic_name, characteristic_value 
        FROM unit_characteristics";
$stmt = $pdo->query($sql);

$objects = array();
while ($row = $stmt->fetch()) {
  if (!isset($objects[ $row["uut_sn"] ])) {
      $object[ $row["uut_sn"] ] = new Uut();
  }
  $objects[ $row["uut_sn"] ]->$row["characteristic_name"] 
                            = $row["characterstic_value"];
}

これには、クエリで特性名をハードコーディングするソリューションに比べていくつかの利点があります。

  • このソリューションは、2つではなく1つのSQLクエリのみを使用します。
  • 動的SQLクエリを作成するために複雑なコードは必要ありません。
  • 特性の1つを忘れた場合でも、このソリューションは自動的にそれを検出します。
  • MySQLのGROUPBYは低速であることが多く、これによりGROUPBYが回避されます。
于 2010-08-18T18:29:16.740 に答える