Postgresql:以下选择是否合理/可能?
客户希望我创建如下所示的数据集。我不知道这是可能的还是合乎逻辑的 我有表家长:Postgresql:以下选择是否合理/可能?,postgresql,Postgresql,客户希望我创建如下所示的数据集。我不知道这是可能的还是合乎逻辑的 我有表家长: id name ------- ------- 1 parent1 2 parent2 3 parent3 id parent name age ------- ------- ------- ------- 1 1 child1 2 2 1 child2 4 3
id name
------- -------
1 parent1
2 parent2
3 parent3
id parent name age
------- ------- ------- -------
1 1 child1 2
2 1 child2 4
3 1 child3 7
4 2 child12 5
parent child1 child2 child3
------- ------- ------- -------
parent1 2 4 7
parent child12
------- -------
parent2 5
和表子项:
id name
------- -------
1 parent1
2 parent2
3 parent3
id parent name age
------- ------- ------- -------
1 1 child1 2
2 1 child2 4
3 1 child3 7
4 2 child12 5
parent child1 child2 child3
------- ------- ------- -------
parent1 2 4 7
parent child12
------- -------
parent2 5
我想做一个select查询,为parent1返回以下内容:
id name
------- -------
1 parent1
2 parent2
3 parent3
id parent name age
------- ------- ------- -------
1 1 child1 2
2 1 child2 4
3 1 child3 7
4 2 child12 5
parent child1 child2 child3
------- ------- ------- -------
parent1 2 4 7
parent child12
------- -------
parent2 5
当然,请为家长2返回以下内容:
id name
------- -------
1 parent1
2 parent2
3 parent3
id parent name age
------- ------- ------- -------
1 1 child1 2
2 1 child2 4
3 1 child3 7
4 2 child12 5
parent child1 child2 child3
------- ------- ------- -------
parent1 2 4 7
parent child12
------- -------
parent2 5
任何人对此都有解决方案,或者有创意的评论?您可以使用
我将表格定义为:
create table parent (id integer, name text);
create table child (id integer, parent integer, name text, age integer);
要创建透视表,需要指定两个查询,第一个是数据查询,返回(key1,key2,value)的元组:
第二个定义了列名和类型:
select C.name from child C where C.parent = 1
然后使用交叉表功能:
select * from crosstab(
$$ SELECT P.name, C.name, C.age from parent P, child C where P.id = C.parent and C.parent = 1 $$,
$$ select C.name from child C where C.parent = 1 $$
) AS (name text, child1 integer, child2 integer, child3 integer);
name | child1 | child2 | child3
---------+--------+--------+--------
parent1 | 2 | 4 | 7
(1 row)
请注意动态生成此标签有点棘手,因为您需要指定列类型(作为交叉表函数之后的一部分),这意味着您需要进行另一次查询以了解将有多少不同的标签(本例中为child1、child2和child3)
Buuut,虽然这个查询是可能的,但它可能不是解决问题的最佳案例。在进行分析时,我将其用作助手,即使这样,在Excel/LibreCalc中仅导出(key1,key2,value)表和数据透视通常也更容易。Crosstab也只有两个键的限制,Excel支持更多的字段,并且可以快速轻松地拖动它们。如果json足够好:
with parent (id, name) as ( values
(1,'parent1'),
(2,'parent2'),
(3,'parent3')
), child (id, parent, name, age) as ( values
(1,1,'child1',2),
(2,1,'child2',4),
(3,1,'child3',7),
(4,2,'child12',5)
)
select
p.name,
array_agg(array[to_jsonb(c.name), to_jsonb(c.age)]::jsonb[]) as children
from
parent p
inner join
child c on p.id = c.parent
group by p.name
;
name | children
---------+------------------------------------------------------
parent1 | {{"\"child1\"",2},{"\"child2\"",4},{"\"child3\"",7}}
parent2 | {{"\"child12\"",5}}
SQL查询总是返回相同数量的列。因此,单个语句不能一次返回4列,另一次返回2列。唯一的方法是返回子项,例如作为逗号分隔的列表或数组(在单个列中)返回。