sql - 从连接表中选择前 5 行,将其放入较大查询的结果中?

标签 sql sql-server

对垃圾标题表示歉意,但我不知道如何描述我想要做的事情

基本上,我正在尝试编写一个执行相当于以下操作的查询

Firstname  Surname  Phone Number 1   Phone Number 2  ...  Phone Number 5
Bloggs     Joe      012334           09876           ...  05678

从表中

(Person)
id  firstname  surname
1   Joe        Bloggs

(PhoneNumber)
id  personid  number
1   1         01234
2   1         09876
...
5   1         05678

但是我不知道如何在没有重复(和困惑)子查询的情况下做到这一点

例如

SELECT
    Person.firstname,
    Person.surname,
    (SELECT top 1 PhoneNumber.number FROM PhoneNumber WHERE personid = Person.id) as [PhoneNumber1],
    (SELECT top 1 PhoneNumber.number FROM PhoneNumber WHERE personid = Person.id AND
        id NOT IN (SELECT top 1 PhoneNumber.number from PhoneNumber WHERE personid = Person.id)
    ) as [PhoneNumber2],
....

等等。这显然是错误的做法(或者如果不是,这是怪诞、可怕的代码,我会假装我从未见过或参与过)

有什么建议吗?

(另外,我保证这不是家庭作业,也不是我倾向于做的事情......我只是想简化现有的报告)

最佳答案

您可以使用数据透视查询来执行此操作。下面的查询适用于 SQL Server 2012+(因为它使用 concat 运算符),如果您需要使用旧版本,只需更改为该行 我留下了评论。

SELECT * 
FROM Person P
INNER JOIN (
    SELECT 
       Personid, 
       Number, 
       --RN = 'Phone Number ' + CAST(ROW_NUMBER() OVER (PARTITION BY PERSONID ORDER BY ID) AS CHAR(1))
       RN = CONCAT('Phone Number ', ROW_NUMBER() OVER (PARTITION BY PERSONID ORDER BY ID)) 
    FROM PhoneNumber
) PH ON P.ID = PH.PERSONID
PIVOT (
    MAX(Number) FOR RN IN ( 
       [Phone Number 1], 
       [Phone Number 2], 
       [Phone Number 3], 
       [Phone Number 4], 
       [Phone Number 5] 
    )
) AS Pivoted

Sample SQL Fiddle (还有一些虚假数据)

关于sql - 从连接表中选择前 5 行,将其放入较大查询的结果中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26343281/

相关文章:

sql - INSERT IF NOT EXISTS 但以任何一种方式返回身份

sql - 如何在 SQL Server 中获取此列结果

sql-server - sql server 管理控制台不支持多字节字符

sql - 自动生成层次结构值

mysql - 左外连接 ON & AND & WHERE 不起作用?

sql - GROUP BY 和 DISTINCT 有什么区别?

SQL Server 相当于 Oracle 多值 IN 子查询

sql - 从Redshift数据库中删除所有重复项

sql - 查找并替换 LIKE sql 数据

sql - 有没有一种快速方法来检查任何列是否为 NULL?