2017-06-06 102 views
2

所以,我有這個數據存在於一個列中。奇數行是ID,偶數行是城市。有沒有辦法將它分成兩列?如何僅基於行號將單列表轉換爲多列?

DECLARE @Data TABLE (
      DataRow  NVARCHAR(50) 
     ) 

    INSERT INTO @Data VALUES 

      ('1'    ) 
     , ('Albuquerque' ) 
     , ('2'    ) 
     , ('Boston'  ) 
     , ('3'    ) 
     , ('Chicago'  ) 
     , ('4'    ) 
     , ('Dayton'  ) 
     , ('5'    ) 
     , ('Eumenclaw'  ) 
     , ('6'    ) 
     , ('Fresno'  ) 

現在,我使用下面的代碼,但它好像應該是使用數據透視表更有效的方式。

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 

結果:

enter image description here

哦,對不住那些你從華盛頓的拼寫錯誤。希望不是新墨西哥州。

回答

4

這將適用於您的小表變量,但是,如果來自表,沒有固有的行順序,並且結果不能是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 

返回

ID City 
1 Albuquerque 
2 Boston 
3 Chicago 
4 Dayton 
5 Eumenclaw 
6 Fresno 
+0

哇。我在這裏一直受到思想和專業知識的吹捧。這真是不可思議。當然,我修改了它(不能在這裏發佈真實的數據,所以我使用軼事)。我擁有的數據是完全可預測的,所以我可以在ID上使用MOD功能。但是,你給了我我需要的東西,謝謝。輝煌。 – DaveX

+0

@DaveX快樂它幫助:) –

+0

@DaveX我也喜歡SO。我每天都會學到新的東西。這是有趣的部分 –

0

又一選項,以確保正確的順序是具有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 

返回

ID City 
1 Albuquerque 
2 Boston 
3 Chicago 
4 Dayton 
5 Eumenclaw 
6 Fresno