我有下表...
ID Phone Address
1 502 100 Main
1 602 100 Main
2 502 500 S Main
3 444 201 N Point
3 777 201 N Point
4 111 999 South
我想看看......
ID Phone1 Phone2 Phone3 Address
1 502 602 100 Main
2 502 500 S Main
3 444 777 201 N Point
4 111 999 South
我可以拥有超过2个手机号码,我认为可能是Pivot,但我不确定任何帮助是否值得赞赏。
答案 0 :(得分:0)
If Object_Id('tempdb.dbo.#test') Is Not Null
Begin
Drop Table #test;
End
If Object_Id('tempdb.dbo.#finalResult') Is Not Null
Begin
Drop Table #finalResult;
End
If Object_Id('tempdb.dbo.#test') Is Null
Begin
Create Table #test
(
RowId Int Identity(1,1) Primary Key
,Id Int
,Phone Varchar(100)
,Address Varchar(2000)
,PhoneUId Int Default 0
)
End
If Object_Id('tempdb.dbo.#finalResult') Is Null
Begin
Create Table #finalResult
(
Id Int Primary Key
)
End
Declare @MaxPhoneCount Int
,@PhoneLoop Int
,@SqlToRun Varchar(5000)
Select @SqlToRun = ''
Insert Into #test (Id,Phone,Address) Values
(1,'502','100 Main')
,(1,'602','100 Main')
,(2,'502','500 S Main')
,(2,'622','500 S Main')
,(2,'782','500 S Main')
,(3,'444','201 N Point')
,(3,'777','201 N Point')
,(4,'111','999 South');
Update t
Set t.PhoneUId = t1.PhoneUid
From #test As t
Join
(
Select t.RowId
,ROW_NUMBER() Over(Partition By t.Id Order By t.Id) As PhoneUid
From #test As t With (Nolock)
) As t1 On t.RowId = t1.RowId
Select @MaxPhoneCount = Max(tr.PhoneCount)
,@PhoneLoop = 1
From (
Select t.Id
,Count(t.Phone) As PhoneCount
From #test As t With (Nolock)
Group By t.Id
) As tr
Select @SqlToRun = 'Alter Table #finalResult Add '
While (@PhoneLoop <= @MaxPhoneCount)
Begin
Select @SqlToRun = @SqlToRun + (Case When @PhoneLoop > 1 Then ',' Else '' End) + ' Phone' + Cast(@PhoneLoop As Varchar(100)) + ' Varchar(100)'
Select @PhoneLoop = @PhoneLoop + 1
End
Select @SqlToRun = @SqlToRun + ',' + ' Address Varchar(2000)'
----Print (@SqlToRun)
Exec (@SqlToRun)
Insert Into #finalResult(Id,Address)
Select Distinct
t.Id
,t.Address
From #test As t With (Nolock)
Select @SqlToRun = ''
,@PhoneLoop = 1
While (@PhoneLoop <= @MaxPhoneCount)
Begin
Select @SqlToRun = 'Update fr Set fr.Phone' + Cast(@PhoneLoop As Varchar(20)) + ' = t.Phone From #finalResult As fr With (Nolock) ' +
'Join #test As t With (Nolock) On fr.Id = t.Id Where t.PhoneUId =' + Cast(@PhoneLoop As Varchar(20)) + ';'
----Print (@SqlToRun)
Exec (@SqlToRun)
Select @PhoneLoop = @PhoneLoop + 1
,@SqlToRun = ''
End
Select *
From #finalResult As fr With (Nolock)
答案 1 :(得分:0)
以下脚本会为您提供所需的结果。它首先确定任何ID的最大电话号码数。然后使用最大数量的电话号码(形式为'[Phone 1],...,[Phone N]',其中N为最大数量)构建带有枢轴列的字符串。最后,使用PIVOT列构建动态SQL语句,然后执行该语句。
CREATE TABLE #t(
ID INT,
Phone INT,
[Address] VARCHAR(256)
);
INSERT INTO #t
(ID,Phone,[Address])
VALUES
(1,502,'100 Main'),
(1,602,'100 Main'),
(2,502,'500 S Main'),
(3,444,'201 N Point'),
(3,777,'201 N Point'),
(4,111,'999 South');
DECLARE @MaxPhoneCount INT;
SELECT
@MaxPhoneCount=MAX(pc.PhoneCount)
FROM
(
SELECT
ID,
COUNT(*) AS PhoneCount
FROM
#t
GROUP BY
ID
) AS pc;
DECLARE @PhoneIDS VARCHAR(8000);
DECLARE @i INT=1;
WHILE @i<=@MaxPhoneCount
BEGIN
SET @PhoneIDS=
CASE WHEN @PhoneIDS IS NULL
THEN '[Phone '+CAST(@i AS VARCHAR(2))+']'
ELSE @PhoneIDS+',[Phone '+CAST(@i AS VARCHAR(2))+']'
END;
SET @i=@i+1;
END
DECLARE @sql VARCHAR(MAX);
SET @sql='
SELECT
*
FROM
(
SELECT
ID,
Phone,
''Phone '' + CAST(ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Phone) AS VARCHAR(2)) AS PhoneLabel,
[Address]
FROM
#t
) AS p
PIVOT(
MAX(Phone)
FOR PhoneLabel IN ('+@PhoneIDS+')
) AS piv
ORDER BY
ID';
EXEC (@sql);
DROP TABLE #t;
此脚本的结果是:
ID Address Phone 1 Phone 2
1 100 Main 502 602
2 500 S Main 502 NULL
3 201 N Point 444 777
4 999 South 111 NULL