您可以使用CTE收集數據,同時將電話號碼旋轉到以逗號分隔的列表中。這可能不是有效的,但它是一個方便的技巧。
上AdventureWorks2008R2以下運行,但你需要的東西在Person.PersonPhone表中的一些額外的數據爲單人/號碼類型創建多個電話號碼。
; with PersonsWithTelephoneNumbersCTE (
BusinessEntityId, FirstName, MiddleName, LastName,
PhoneNumberTypeId, PhoneNumber, PhoneNumbers, Elements)
as (
-- Base case: Just the person identifications with all possible phone types.
select BusinessEntityID, FirstName, MiddleName, LastName, PhoneNumberTypeId,
cast('' as NVarChar(25)), cast('' as VarChar(MAX)), 0
from Person.Person as PP cross join
Person.PhoneNumberType as PNT
union all
-- Add a telephone number.
select CTE.BusinessEntityId, CTE.FirstName, CTE.MiddleName, CTE.LastName,
PNT.PhoneNumberTypeID, PN.PhoneNumber,
cast(CTE.PhoneNumbers + ', ' + PN.PhoneNumber as VarChar(MAX)), CTE.Elements + 1
from PersonsWithTelephoneNumbersCTE as CTE inner join
Person.Person as PP on PP.BusinessEntityID = CTE.BusinessEntityId inner join
Person.PhoneNumberType as PNT on PNT.PhoneNumberTypeID = CTE.PhoneNumberTypeId inner join
Person.PersonPhone as PN on PN.BusinessEntityID = CTE.BusinessEntityId and PN.PhoneNumberTypeID = PNT.PhoneNumberTypeID
where PN.PhoneNumber > CTE.PhoneNumber
)
-- Get the person and the longest list of phone numbers for each person/phone type.
select LastName, FirstName, MiddleName,
(select Name from Person.PhoneNumberType where PhoneNumberTypeID = Edna.PhoneNumberTypeID) as PhoneNumberType,
substring(PhoneNumbers, 3, len(PhoneNumbers) - 2) as PhoneNumbers from (
select BusinessEntityID, FirstName, MiddleName, LastName, PhoneNumberTypeId, PhoneNumbers,
rank() over (partition by BusinessEntityId, PhoneNumberTypeId order by Elements desc) as Ranking
from PersonsWithTelephoneNumbersCTE
) as Edna
where Ranking = 1 and PhoneNumbers <> ''
order by LastName, FirstName, MiddleName, PhoneNumberType
我不明白你在問什麼。你能重述嗎? – 2011-09-03 08:09:32
偏題:你問的是可能的。首先,這是由.NET應用程序消耗嗎?我問,因爲LINQ中的轉置要乾淨得多 –
@ Neil Fenwick 是的。請你解釋一下如何使用LINQ來做這件事?的 – Shahin