如何使用 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).输入日期也不对应于输出日期。您发现存在一致性问题。
但是为了根据需要组织输出,您试图一次做太多事情。而不是单个表达式将 availableunavailable 分开,然后聚合结果。以下在子查询中将它们分开,然后主查询聚合。参见 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;

备注:

  1. 避免双引号 table 和列名,它们是不值得的。
  2. 不要使用date作为列名。它是 Postgres 数据类型和 SQL 标准保留字。虽然你摆脱了 Postgres 开发人员的权利,但他们有权要求按定义使用它。从而使您的所有工作无效。适用于任何数据类型或保留字。