PostgreSQL - 如何在条件后连接行值
Posted
技术标签:
【中文标题】PostgreSQL - 如何在条件后连接行值【英文标题】:PostgreSQL - How to concatenate row values after a conditional 【发布时间】:2021-03-22 05:47:45 【问题描述】:我在 postgres 中有一张桌子:
| 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 |
我已经有了这个脚本,但是我没有 ref 代码列的 concat 部分:
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
请帮忙!并提前感谢
【问题讨论】:
【参考方案1】:您只需要将这些列与双管道字符连接起来,例如
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
列(只要description
s 是Height
或Weight
)这样作为
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
【讨论】:
但是如果在参考文献中呢?代码我们需要其他不是我们选择的值(姓名、姓氏、年龄和国家)?假设它们是身高和体重,我们不想选择它们作为列 但您的问题并没有说明您在@FranciscoEnriqueGiménezVera 评论中的解释。请在按下 edit 按钮后用详细的示例和信息更新问题。【参考方案2】:您可以使用字符串聚合。此外,在 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
【讨论】:
以上是关于PostgreSQL - 如何在条件后连接行值的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel 8 中使用 PostgreSQL 中的子查询通过 group by 子句获取行值?
如何在 pandas.DataFrame 中插入满足条件的行值
如何根据条件行值对 pandas 数据框进行取消堆叠或取消透视?