从连接表中选择前5行,进入较大查询的结果?

时间:2014-10-13 15:13:52

标签: 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],
....

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

有什么建议吗?

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

2 个答案:

答案 0 :(得分:2)

您可以使用数据透视查询来执行此操作。下面的查询适用于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(还有一些假数据)

答案 1 :(得分:0)

MSSQL 2012的可能解决方案是使用OFFSET

SELECT
    Person.firstname,
    Person.surname,
    (SELECT number FROM PhoneNumber WHERE PhoneNumber.personid = Person.id 
     ORDER BY PhoneNumber.id OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY) AS number1,
    (SELECT number FROM PhoneNumber WHERE PhoneNumber.personid = Person.id 
     ORDER BY PhoneNumber.id OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY) AS number2,
    ...
FROM
    Person

请参阅此Fiddle