我正在研究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个条目。某种方向将非常受欢迎。
答案 0 :(得分: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 extension的手册,特别是crosstab(text, text)
:
我已经发布了一些关于tablefunc模块的crosstab()
函数的答案。 This search将为您提供更多示例和解释。