您可以使用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