我有两个表,things
和properties
:
CREATE TABLE things (
id SERIAL PRIMARY KEY
);
CREATE TABLE properties (
thing_id INT,
key TEXT,
value TEXT
);
我想从things
中选择并加入properties
中的行作为列。例如,假设我有以下内容:
INSERT INTO things DEFAULT_VALUES; -- suppose id is 1
INSERT INTO properties (thing_id, key, value) VALUES
(1, 'height', '5'),
(1, 'width', '6'),
(1, 'length', '7');
如何选择height
,width
和length
作为列的内容?
此外,我不希望具体选择height
,width
和length
,但是可能在属性中的所有行。
答案 0 :(得分:2)
只有三列:
SELECT t.thing_id
,max(CASE WHEN p.key = 'height' THEN p.value END) AS height
,max(CASE WHEN p.key = 'width' THEN p.value END) AS width
,max(CASE WHEN p.key = 'length' THEN p.value END) AS length
FROM things t
LEFT JOIN properties p ON p.thing_id = t.id
WHERE t.id = 1
GROUP BY 1;
或者使用附加模块crosstab()
中的tablefunc
,这通常更快,而且对于长属性列表更短:
SELECT * FROM crosstab(
'SELECT t.thing_id, p.key, p.value
FROM things t
LEFT JOIN properties p ON p.thing_id = t.id
WHERE t.id = 1
ORDER BY 1'
,$$VALUES ('height'::text), ('width'), ('length')$$) -- add more
AS ct (thing_id int, height int, width int, length int); -- add more
类型必须匹配。详细解释:
在单个查询中无法实现完全动态列列表。我已多次尝试过。以下是可以完成的事情:
答案 1 :(得分:0)
可能你可以在这里尝试表别名:
SELECT p1.key, p2.key, p3.key
FROM properties as t1
JOIN properties AS p1 ON p1.thing_id= t1.thing_id
JOIN properties AS p2 ON p2.thing_id= t1.thing_id
JOIN properties AS p3 ON p3.thing_id= t1.thing_id
WHERE t1.thing_id = 1;