如何使用 postgres 将 array_agg 中的条件结果合并为一行?
How to get the results of conditions in array_agg into one line using postgres?
我需要处理这个 table,根据 postgres exception_type 中的值将数据分成列。
service_id, date, exception_type
...
"2:11:CIST-100385-1-2023",2020-12-24,"2"
"2:11:CIST-100385-1-2023",2020-12-26,"2"
"2:11:CIST-100385-1-2023",2021-04-02,"1"
"2:11:CIST-100385-1-2024",2020-12-24,"1"
"2:11:CIST-100385-1-2024",2021-11-17,"1"
"2:11:CIST-100385-1-2024",2020-12-26,"2"
...
我的代码:
SELECT service_id,
case
when calendardates.exception_type='1' then array_to_string(array_agg(concat(calendardates.date,' ')), ', ')
end as availabe,
case
when calendardates.exception_type='2' then array_to_string(array_agg(concat(calendardates.date,' ')), ', ')
end as unavailable
FROM calendardates
group by service_id ,exception_type
此查询的输出是一个包含合并数据的 table,但总是一列包含值,另一列包含空值。
我需要每个 service_id 一次,包括可用和不可用日期。
这是我得到的:
service_id, availabe, unavailabe
"2:100:CIST-595009-1-301","2021-12-26,2021-04-02,2021-04-05","[null]"
"2:100:CIST-595009-1-301","[null]","2021-01-01,2020-12-25"
"2:100:CIST-595009-1-302","2021-09-28,2021-05-08,2020-12-26","[null]"
"2:100:CIST-595009-1-302","[null]","2020-12-25,2021-01-01"
这是我需要的:
service_id, availabe, unavailabe
"2:100:CIST-595009-1-301","2021-12-26,2021-04-02,2021-04-05","2021-01-01,2020-12-25"
"2:100:CIST-595009-1-302","2021-09-28,2021-05-08,2020-12-26","2020-12-25,2021-01-01"
不幸的是,鉴于所提供的输入,无法获得您想要的结果。你必须解释 service_id "2:11:CIST-100385-1-2023" 如何被翻译成 "2:100:CIST-595009-1-301" (或者它是 2:...- 302).输入日期也不对应于输出日期。您发现存在一致性问题。
但是为了根据需要组织输出,您试图一次做太多事情。而不是单个表达式将 available
与 unavailable
分开,然后聚合结果。以下在子查询中将它们分开,然后主查询聚合。参见 here。
select service_id
, string_agg( availabe, ', ' ) availabe
, string_agg( unavailabe, ', ' ) unavailabe
from (select service_id
, case when c.exception_type='1' then c.date::text end as availabe
, case when c.exception_type='2' then c.date::text end as unavailabe
from calendardates c
) s
group by service_id;
备注:
- 避免双引号 table 和列名,它们是不值得的。
- 不要使用
date
作为列名。它是 Postgres 数据类型和 SQL 标准保留字。虽然你摆脱了 Postgres 开发人员的权利,但他们有权要求按定义使用它。从而使您的所有工作无效。适用于任何数据类型或保留字。
我需要处理这个 table,根据 postgres exception_type 中的值将数据分成列。
service_id, date, exception_type
...
"2:11:CIST-100385-1-2023",2020-12-24,"2"
"2:11:CIST-100385-1-2023",2020-12-26,"2"
"2:11:CIST-100385-1-2023",2021-04-02,"1"
"2:11:CIST-100385-1-2024",2020-12-24,"1"
"2:11:CIST-100385-1-2024",2021-11-17,"1"
"2:11:CIST-100385-1-2024",2020-12-26,"2"
...
我的代码:
SELECT service_id,
case
when calendardates.exception_type='1' then array_to_string(array_agg(concat(calendardates.date,' ')), ', ')
end as availabe,
case
when calendardates.exception_type='2' then array_to_string(array_agg(concat(calendardates.date,' ')), ', ')
end as unavailable
FROM calendardates
group by service_id ,exception_type
此查询的输出是一个包含合并数据的 table,但总是一列包含值,另一列包含空值。 我需要每个 service_id 一次,包括可用和不可用日期。
这是我得到的:
service_id, availabe, unavailabe
"2:100:CIST-595009-1-301","2021-12-26,2021-04-02,2021-04-05","[null]"
"2:100:CIST-595009-1-301","[null]","2021-01-01,2020-12-25"
"2:100:CIST-595009-1-302","2021-09-28,2021-05-08,2020-12-26","[null]"
"2:100:CIST-595009-1-302","[null]","2020-12-25,2021-01-01"
这是我需要的:
service_id, availabe, unavailabe
"2:100:CIST-595009-1-301","2021-12-26,2021-04-02,2021-04-05","2021-01-01,2020-12-25"
"2:100:CIST-595009-1-302","2021-09-28,2021-05-08,2020-12-26","2020-12-25,2021-01-01"
不幸的是,鉴于所提供的输入,无法获得您想要的结果。你必须解释 service_id "2:11:CIST-100385-1-2023" 如何被翻译成 "2:100:CIST-595009-1-301" (或者它是 2:...- 302).输入日期也不对应于输出日期。您发现存在一致性问题。
但是为了根据需要组织输出,您试图一次做太多事情。而不是单个表达式将 available
与 unavailable
分开,然后聚合结果。以下在子查询中将它们分开,然后主查询聚合。参见 here。
select service_id
, string_agg( availabe, ', ' ) availabe
, string_agg( unavailabe, ', ' ) unavailabe
from (select service_id
, case when c.exception_type='1' then c.date::text end as availabe
, case when c.exception_type='2' then c.date::text end as unavailabe
from calendardates c
) s
group by service_id;
备注:
- 避免双引号 table 和列名,它们是不值得的。
- 不要使用
date
作为列名。它是 Postgres 数据类型和 SQL 标准保留字。虽然你摆脱了 Postgres 开发人员的权利,但他们有权要求按定义使用它。从而使您的所有工作无效。适用于任何数据类型或保留字。