2017-06-06 4 views
2

したがって、このデータは1つの列にあります。奇数行はID、偶数行は都市です。これを2つの列に分割する方法はありますか?行番号だけに基づいて、単一の列テーブルを複数の列に変換するにはどうすればよいですか?

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あまりにも大好きです。私は毎日何か新しいことを学びます。それは楽しい部分です –

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 
関連する問題