为垃圾标题道歉,但我想不出如何描述我想要做的事情
基本上我正在尝试编写一个与以下内容相同的查询
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],
....
等。这显然是错误的做法(或者如果没有,它是怪诞的,可怕的代码,我假装我从未见过或参与其中)
有什么建议吗?
(另外,我保证这不是家庭作业,也不是我倾向于做的事情......我只是想简化现有的报告)
答案 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。