将子查询的结果聚合为逗号分隔值
Posted
技术标签:
【中文标题】将子查询的结果聚合为逗号分隔值【英文标题】:Aggregate result of sub query to comma separated values 【发布时间】:2021-07-02 23:09:10 【问题描述】:如何以逗号分隔值的形式获取子查询的结果。
我有三个表,location
和 stock_location_type
和 location_label
。
我正在加入 location 和 stock_location_type 并且基于 SLT.inventory_location_cd
的结果,我正在查询另一个表 location_label
。
为此,我正在编写以下查询。
select L.stock_catalogue_id, SLT.inventory_location_cd,
case
when nventory_location_cd = 'base location' then (select related_location_id from location_label where base_location_id = location_id)
when nventory_location_cd != 'base location' then (select base_location_id from location_label where related_location_id = location_id)
end as "Current Location",
* from location L
join stock_location_type SLT on L.stock_location_type_id = SLT.stock_location_type_id;
这些子查询返回多行。
我尝试使用 string_agg 并转换 related_location_id 和 base_location_id(因为它们是 UUID)。但随后它抱怨 group by。
如果我使用 group by 那么它会出错,'multiple rows returned by subquery'
。
我错过了什么?
【问题讨论】:
【参考方案1】:您可以使用string_agg 函数来聚合逗号分隔字符串中的值。所以你的子查询需要重写为
select string_agg(related_location_id, ', ') from location_label where base_location_id = location_id
和
select string_agg(base_location_id, ', ') from location_label where related_location_id = location_id
【讨论】:
【参考方案2】:我用
重新创建了你的表集location_label
表
create table location_label(location_id int, location_label varchar);
insert into location_label values(1, 'Home');
insert into location_label values(2, 'Office');
insert into location_label values(3, 'Garage');
insert into location_label values(4, 'Bar');
stock_location_type
表
create table stock_location_type (stock_location_type_id int, inventory_location_cd varchar);
insert into stock_location_type values(1, 'base location');
insert into stock_location_type values(2, 'Not base location');
location
表
create table location (stock_catalogue_id int, base_location_id int, related_location_id int, stock_location_type_id int);
insert into location values(1,1,2,1);
insert into location values(1,2,1,2);
insert into location values(1,3,3,1);
insert into location values(2,4,3,1);
insert into location values(2,3,1,1);
insert into location values(2,2,4,2);
如果我正确理解您的陈述,您将尝试使用base_location_id
或location_id
基于inventory_location_cd
列加入location
和location_label
表。
如果这是您想要实现的目标,那么下面的查询应该可以做到。通过将连接条件移动到适当的位置
select L.stock_catalogue_id,
SLT.inventory_location_cd,
location_id "Current Location Id",
location_label "Current Location Name"
from location L join stock_location_type SLT
on L.stock_location_type_id = SLT.stock_location_type_id
left outer join location_label
on (
case when
inventory_location_cd = 'base location'
then base_location_id
else related_location_id
end) = location_id
;
结果是
stock_catalogue_id | inventory_location_cd | Current Location Id | Current Location Name
--------------------+-----------------------+---------------------+-----------------------
1 | base location | 1 | Home
1 | Not base location | 1 | Home
1 | base location | 3 | Garage
2 | base location | 3 | Garage
2 | base location | 4 | Bar
2 | Not base location | 4 | Bar
(6 rows)
如果您需要通过stock_catalogue_id
和inventory_location_cd
将其聚合起来,可以使用
select L.stock_catalogue_id,
SLT.inventory_location_cd,
string_agg(location_id::text, ',') "Current Location Id",
string_agg(location_label::text, ',') "Current Location Name"
from location L join stock_location_type SLT
on L.stock_location_type_id = SLT.stock_location_type_id
left outer join location_label
on (case when inventory_location_cd = 'base location' then base_location_id else related_location_id end) = location_id
group by L.stock_catalogue_id,
SLT.inventory_location_cd;
结果是
stock_catalogue_id | inventory_location_cd | Current Location Id | Current Location Name
--------------------+-----------------------+---------------------+-----------------------
1 | base location | 1,3 | Home,Garage
1 | Not base location | 1 | Home
2 | base location | 3,4 | Garage,Bar
2 | Not base location | 4 | Bar
(4 rows)
【讨论】:
以上是关于将子查询的结果聚合为逗号分隔值的主要内容,如果未能解决你的问题,请参考以下文章