3

我正在使用 PostgreSQL 9.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>

您的问题的解决方案是使用带有两个参数crosstab()的变体。

查询输出所有项目。将子句添加WHERE到第一个查询以过滤类别。

第二个参数(另一个查询字符串)生成输出列的列表,以便NULL正确分配数据查询(第一个参数)中的值。

检查tablefunc 扩展的手册,特别是crosstab(text, text)

我已经发布了一些关于crosstab()tablefunc 模块功能的答案。此搜索将为您提供更多示例和解释。

于 2012-07-13T20:05:12.237 回答