Postgresql中的转置

myzjeezk  于 2023-01-25  发布在  PostgreSQL
关注(0)|答案(2)|浏览(269)

我正在尝试设计一个客户详细信息的数据库。在那里客户可以有多达两个不同的电话号码。
当我运行Select * 命令以显示符合条件的客户时,我得到以下结果:

Name  |  Number
James |   12344532
James  |  23232422

我希望它以如下方式显示所有带有两个数字的客户:

Name  |   Number  | Number
James     12344532   23232422
John      32443322
Jude      12121212   23232422

我正在Azure Data Studio上使用Postgresql服务器。
请协助。
我尝试使用以下命令:

Select * FROM name.name,
min(details.number) AS number1,
max(details.number) AS number2
FROM name
JOIN details
ON name.id=details.id
GROUP BY name.name

我有这个

Name  |   Number  | Number

James     12344532   23232422

John      32443322   32443322

Jude      12121212   23232422

只有一个电话号码的客户在表中重复。我该如何处理?

fbcarpbf

fbcarpbf1#

我将这些数字聚合成一个数组,然后提取数组元素:

select n.name, 
       d.numbers[1] as number_1,
       d.numbers[2] as number_2
from name n
  join (
    select id, array_agg(number) as numbers
    from details
    group by id
  ) d on d.id = n.id
order by name;

如果您有两个以上的数字,这也很容易扩展。

ffx8fchx

ffx8fchx2#

请尝试使用以下查询:

SELECT 
    Name,
    MIN(CASE WHEN rn = 1 THEN Number END) AS Number1,
    MIN(CASE WHEN rn = 2 THEN Number END) AS Number2
FROM
    (SELECT 
        Name, Number,
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Number) AS rn
    FROM name) t
GROUP BY  Name

此查询将使用ROW_NUMBER()函数为每个客户的每个电话号码分配唯一的行号。ROW_NUMBER()函数按Number列排序,因此最小的数字将具有行号1,第二小的数字将具有行号2,依此类推。
然后使用外部查询按名称对客户进行分组,并使用MIN()函数根据行号获得第一个和第二个编号。
此查询将返回所需的输出,其中包含两列,一列显示客户的第一个电话号码,另一列显示他们的第二个电话号码。
注:上述查询假定每个客户的电话号码都是唯一的。如果客户具有重复的电话号码,查询将返回遇到的第一个电话号码。

相关问题