PostgreSQL - 如何在条件后连接行值

PostgreSQL - How to concatenate row values after a conditional

我在 postgres 中有一个 table:

| PersonID |Description | Value |
|----------|-------------|-------|
|     1    | Name        | Jane  |
|     1    | Last name   | Doe   |
|     1    | Age         | 23    |
|     1    | Country     | USA   |
|     2    | Name        | Steve |
|     2    | Last name   | Jobs  |
|     2    | Age         | 40    |
|     2    | Country     | India |
|     1    | Height      | 1.80  |
|     1    | Weight      | 80    |
|     2    | Height      | 1.72  |
|     2    | Weight      | 79    |

我想要这个(obs:参考代码 = 身高+体重):

| Name    | Last_name | Age | Country | Ref. code |
|---------|-----------|-----|---------|-----------|
| Jane    | Doe       | 23  | USA     | 1.8080    |
| Steve   | Jobs      | 40  | India   | 1.7279    |

我已经有了这个脚本,但我没有参考代码列的连接部分:

select person_id,
    max(case when description = 'Name' then value end) as name,
    max(case when description = 'Last name' then value end) as last_name,
    max(case when description = 'Age' then value end) as age,
    max(case when description = 'Country' then value end) as country
from mytable
group by person_id

请帮忙!提前致谢

您只需将这些列与双管道字符连接起来,例如

select q.*,
       name||last_name||country as "Ref. code"
  from
  (
   select person_id,
          max(case when description = 'Name' then value end) as name,
          max(case when description = 'Last name' then value end) as last_name,
          max(case when description = 'Age' then value end) as age,
          max(case when description = 'Country' then value end) as country
     from mytable
    group by person_id
  ) q

更新: 在您当前的情况下,您可以将 string_agg() 函数应用于具有条件的单个 value 列(每当 descriptions是 HeightWeight) 例如

select person_id,
       max(case when description = 'Name' then value end) as name,
       max(case when description = 'Last name' then value end) as last_name,
       max(case when description = 'Age' then value end) as age,
       max(case when description = 'Country' then value end) as country,
       string_agg(case when Description in ('Height','Weight') then value end,'') as "Ref. code"
  from mytable
 group by person_id

Demo

您可以使用字符串聚合。此外,在 Postgrs 中,我们可以使用 filter():

简化聚合表达式
select person_id,
    max(value) filter(where description = 'Name'     ) as name,
    max(value) filter(where description = 'Last name') as last_name,
    max(value) filter(where description = 'Age'      ) as age,
    max(value) filter(where description = 'Country'  ) as age,
    string_agg(value, '-' order by description) filter(where description in ('Name', 'Last name', 'Country')) as ref_code
from mytable
group by person_id

这使您可以灵活地向参考代码添加您喜欢的任何描述,即使它不是由其他聚合函数返回的。

我建议在 ref 部分之间添加一个分隔符,这样它的组成方式就更清楚了。我使用了 '-'(如果您不需要分隔符,可以将其更改为 '')。

请注意,这按描述对值进行排序。如果你真的想微调排序,那么你可以在聚合函数的order by子句中使用一个case表达式:

string_agg(
    value, 
    '-' 
    order by case description
        when 'Name'      then 1
        when 'Last name' then 2
        when, 'Country'  then 3
    end
) filter(where description in ('Name', 'Last name', 'Country')) as ref_code