如何仅根据行号将单列 table 变成多列?
How do I turn a single column table into multiple columns based solely on row number?
因此,我将此数据存在于单个列中。奇数行是ID,偶数行是城市。有没有办法将其分成两列?
DECLARE @Data TABLE (
DataRow NVARCHAR(50)
)
INSERT INTO @Data VALUES
('1' )
, ('Albuquerque' )
, ('2' )
, ('Boston' )
, ('3' )
, ('Chicago' )
, ('4' )
, ('Dayton' )
, ('5' )
, ('Eumenclaw' )
, ('6' )
, ('Fresno' )
现在我正在使用以下代码,但似乎应该有更有效的方法来使用枢轴 table。
DECLARE @DataID TABLE (
ID INT IDENTITY
, DataRow NVARCHAR(50)
)
INSERT INTO @DataID
SELECT * FROM @Data
DECLARE @CityData TABLE (
ID INT
, City NVARCHAR(100)
)
DECLARE @Counter INT = 0
, @ID INT
, @City NVARCHAR(50)
WHILE @Counter < (SELECT MAX(ID) / 2 FROM @DataID WHERE ID%2 = 0)
BEGIN
SET @Counter += 1
SET @ID = (SELECT CAST(DataRow AS INT) FROM @DataID WHERE ID = @Counter * 2 - 1)
SET @City = (SELECT DataRow FROM @DataID WHERE ID = @Counter * 2)
INSERT INTO @CityData
SELECT @ID, @City
END
SELECT * FROM @CityData
结果:
哦,对于拼写错误,向来自华盛顿的那些人道歉。希望不是新墨西哥州。
这将适用于您的小 table 变量,但是,如果来自 table,则没有固有的行顺序,结果可以不是 gtd.
例子
Select ID = max(case when DataRow Like '[0-9]%' then DataRow end)
,City = max(case when DataRow Not Like '[0-9]%' then DataRow end)
From (
Select *
,Grp = (Row_Number() over (Order by (Select NULL)) -1) / 2
From @Data
) A
Group By Grp
Returns
ID City
1 Albuquerque
2 Boston
3 Chicago
4 Dayton
5 Eumenclaw
6 Fresno
另一种选择,以确保正确的顺序是将数据解析为带有 CRLF 定界符的字符串
考虑以下因素:
Declare @Delimiter varchar(25) = char(13)+char(10)
Declare @String varchar(max) = '
1
Albuquerque
2
Boston
3
Chicago
4
Dayton
5
Eumenclaw
6
Fresno
'
Select ID = max(case when RetSeq % 2 = 1 then RetVal end)
,City = max(case when RetSeq % 2 = 0 then RetVal end)
From (
Select *,Grp = (RetSeq-1) / 2
From (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
Where LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) is not null
) A1
) A
Group By Grp
Returns
ID City
1 Albuquerque
2 Boston
3 Chicago
4 Dayton
5 Eumenclaw
6 Fresno
因此,我将此数据存在于单个列中。奇数行是ID,偶数行是城市。有没有办法将其分成两列?
DECLARE @Data TABLE (
DataRow NVARCHAR(50)
)
INSERT INTO @Data VALUES
('1' )
, ('Albuquerque' )
, ('2' )
, ('Boston' )
, ('3' )
, ('Chicago' )
, ('4' )
, ('Dayton' )
, ('5' )
, ('Eumenclaw' )
, ('6' )
, ('Fresno' )
现在我正在使用以下代码,但似乎应该有更有效的方法来使用枢轴 table。
DECLARE @DataID TABLE (
ID INT IDENTITY
, DataRow NVARCHAR(50)
)
INSERT INTO @DataID
SELECT * FROM @Data
DECLARE @CityData TABLE (
ID INT
, City NVARCHAR(100)
)
DECLARE @Counter INT = 0
, @ID INT
, @City NVARCHAR(50)
WHILE @Counter < (SELECT MAX(ID) / 2 FROM @DataID WHERE ID%2 = 0)
BEGIN
SET @Counter += 1
SET @ID = (SELECT CAST(DataRow AS INT) FROM @DataID WHERE ID = @Counter * 2 - 1)
SET @City = (SELECT DataRow FROM @DataID WHERE ID = @Counter * 2)
INSERT INTO @CityData
SELECT @ID, @City
END
SELECT * FROM @CityData
结果:
哦,对于拼写错误,向来自华盛顿的那些人道歉。希望不是新墨西哥州。
这将适用于您的小 table 变量,但是,如果来自 table,则没有固有的行顺序,结果可以不是 gtd.
例子
Select ID = max(case when DataRow Like '[0-9]%' then DataRow end)
,City = max(case when DataRow Not Like '[0-9]%' then DataRow end)
From (
Select *
,Grp = (Row_Number() over (Order by (Select NULL)) -1) / 2
From @Data
) A
Group By Grp
Returns
ID City
1 Albuquerque
2 Boston
3 Chicago
4 Dayton
5 Eumenclaw
6 Fresno
另一种选择,以确保正确的顺序是将数据解析为带有 CRLF 定界符的字符串
考虑以下因素:
Declare @Delimiter varchar(25) = char(13)+char(10)
Declare @String varchar(max) = '
1
Albuquerque
2
Boston
3
Chicago
4
Dayton
5
Eumenclaw
6
Fresno
'
Select ID = max(case when RetSeq % 2 = 1 then RetVal end)
,City = max(case when RetSeq % 2 = 0 then RetVal end)
From (
Select *,Grp = (RetSeq-1) / 2
From (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
Where LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) is not null
) A1
) A
Group By Grp
Returns
ID City
1 Albuquerque
2 Boston
3 Chicago
4 Dayton
5 Eumenclaw
6 Fresno