3

私はPostgreSQL9.1に取り組んでおり、次の表があります。

element(element_id int, name varchar, category_id int)

category(category_id int, name varchar)

characteristic(characteristic_id int, name varchar, unit varchar)

category_characteristic(characteristic_id, category_id)

element_characteristic(element_id, characteristic_id, value)

次の表を想像してみてください。

elements
 ---------------------
|id|name    |category |
-----------------------
|1 |'item 1'|1        |
|2 |'item 2'|2        |
|3 |'item 3'|1        |
 ---------------------

category
 ----------------
|id|name         |
|----------------|
|1 | 'category 1'|
|2 | 'category 2'|
 ----------------

characteristic
 --------------------------------
|id|name               |unit     |
 --------------------------------
|1 |'characteristic 1' | 'unit 1'| 
|2 |'characteristic 2' | 'unit 2'|
|3 |'characteristic 3' | 'unit 3'|
|4 |'characteristic 4' | 'unit 4'|
|5 |'characteristic 5' | 'unit 5'|
|6 |'characteristic 6' | 'unit 6'|
 --------------------------------

category_characteristic
 ------------------------------
|category_id|characteristic_id |
|------------------------------
|1          |1                 |
|1          |2                 |   
|1          |4                 |
|1          |5                 |
|2          |1                 |
|2          |3                 |
|2          |5                 |
 ------------------------------

element_characteristic
 ---------------------------------------
|id_element|id_characteristic|value     |
|---------------------------------------|
|1         |1                |'value a' |
|1         |2                |'value b' |
|1         |4                |'value c' |
|1         |5                |'value d' |
|2         |1                |'value e' |
|2         |3                |'value f' |
|2         |5                |'value g' |
|3         |1                |'value h' |
|3         |2                |'value i' |
|3         |4                |'value j' |
|3         |5                |'value k' |
 ---------------------------------------

そして今、私は次のテーブルを取得したいと思います:

 category 1
 ---------------------------------------------------------------------------
|name   |characteristic 1|characteristic 2|characteristic 4|characteristic 5|
| --------------------------------------------------------------------------|
|item 1 |value a         |value b         |value c         |value d         |
|item 3 |value h         |value i         |value j         |value k         |
 ---------------------------------------------------------------------------

category 2
 -----------------------------------------------------------
|name   |characteristic 1|characteristic 3|characteristic 5|
| ----------------------------------------------------------
|item 2 |value e         |value f         |value g         |
 ----------------------------------------------------------

私はトラフに行くための最良の手順が何であるかを理解しようとしています。tablefuncのドキュメントを読みましたが、カテゴリテーブルにN個のエントリがあるため、そのプロシージャを動的に作成する方法がわかりません。ある種の方向性は非常に高く評価されます。

4

1 に答える 1

3

解決:

SELECT *
FROM   crosstab (
        'SELECT e.name, c.name, ec.value
         FROM   elements e
         JOIN   element_characteristic ec ON ec.id_element = e.id
         JOIN   characteristic c ON c.id = ec.id_characteristic
         ORDER  BY 1, 2',

        'SELECT DISTINCT name
         FROM   characteristic
         ORDER  BY 1')
AS tbl (
  name text
 ,characteristic_1 text
 ,characteristic_2 text
 ,characteristic_3 text
 ,characteristic_4 text
 ,characteristic_5 text
 ,characteristic_6 text
 );

テスト設定:

CREATE TEMP TABLE elements(id int, name text, category int);
INSERT INTO elements VALUES
 (1, 'item 1', 1)
,(2, 'item 2', 2)
,(3, 'item 3', 1);

CREATE TEMP TABLE element_characteristic(id_element int
                                        ,id_characteristic int, value text);
INSERT INTO element_characteristic VALUES
 (1,1,'value a')
,(1,2,'value b')
,(1,4,'value c')
,(1,5,'value d')
,(2,1,'value e')
,(2,3,'value f')
,(2,5,'value g')
,(3,1,'value h')
,(3,2,'value i')
,(3,4,'value j')
,(3,5,'value k');

CREATE TEMP TABLE characteristic (id int, name text, unit text);
INSERT INTO characteristic VALUES
 (1,'characteristic 1', 'unit 1')
,(2,'characteristic 2', 'unit 2')
,(3,'characteristic 3', 'unit 3')
,(4,'characteristic 4', 'unit 4')
,(5,'characteristic 5', 'unit 5')
,(6,'characteristic 6', 'unit 6');

結果:

  name | characteristic 1 | characteristic_2 | characteristic_3 | characteristic_4 | characteristic_5 | characteristic_6
-------|------------------|------------------|------------------|------------------|------------------|----------------
item 1 | value a          | value b          | <NULL>           | value c          | value d          | <NULL>
item 2 | value e          | <NULL>           | value f          | <NULL>           | value g          | <NULL>
item 3 | value h          | value i          | <NULL>           | value j          | value k          | <NULL>

問題の解決策は、2 つのパラメーターcrosstab()を持つバリアントを使用することです。

クエリはすべての項目を出力します。WHERE最初のクエリに句を追加して、カテゴリをフィルタリングします。

NULL2 番目のパラメーター (別のクエリ文字列) は、データ クエリ (最初のパラメーター) の値が正しく割り当てられるように、出力列のリストを生成します。

tablefunc 拡張機能のマニュアルを確認してください。特にcrosstab(text, text):

crosstab()tablefunc モジュールの機能に関するいくつかの回答を投稿しました。この検索により、より多くの例と説明が得られます。

于 2012-07-13T20:05:12.237 に答える