0

我需要处理这个表,根据 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

此查询的输出是一个包含合并数据的表,但始终有一列具有值,另一列具有空值。我需要每个 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"
4

1 回答 1

0

不幸的是,鉴于提供的输入,不可能获得您想要的结果。您必须解释 service_id "2:11:CIST-100385-1-2023" 是如何转换为 "2:100:CIST-595009-1-301" 的(或者是 2:...-302)。输入日期也不对应于输出日期。你看到有一个一致性问题。
但是为了根据需要组织输出,您一次尝试做太多事情。而不是单个表达式将结果availableunavailable然后聚合结果分开。以下将它们分隔在子查询中,然后将主查询聚合。见这里

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. 避免双引号表和列名,它们只是不值得付出努力。
  2. 不要用作date列名。它是 Postgres 数据类型和 SQL 标准保留字。当您摆脱 Postgres 时,开发人员将在他们的权利范围内要求按照定义使用它。从而使您的所有工作无效。适用于任何数据类型或保留字。
于 2021-09-06T21:16:18.153 回答