0

重複の可能性:
T-SQL: 文字列連結の反対 - 文字列を複数のレコードに
分割する方法 可変長で区切られた文字列を複数の行に分割する (SQL)

次のような列データを含むデータベース テーブルがあります。

Data (field name)
1111,44,666,77
22,55,76,54
32,31,56

これは正規化されていないため、非常に貧弱な設計であることがわかります (私が設計したのではなく、継承したものです)。次のようなデータを返すクエリはありますか。

1111
44
666
77
22
55
76
54
32
31
56

私は CHARINDEX と SUBSTRING の使用に慣れていますが、各セル (コンマで区切られた) の要素数が不明であるため、これを行う方法が思いつきません。

4

5 に答える 5

2

[dbo].[stack] というテーブルを作成し、提供されたデータを入力すると、このスクリプトで必要なものが生成されました。これを行うためのより効率的な方法があるかもしれませんが、これはまさにあなたが要求したとおりに機能します。

    BEGIN
        DECLARE @tmp TABLE (data VARCHAR(20))
        DECLARE @tmp2 TABLE (data VARCHAR(20))

        --Insert all fields from your table
        INSERT INTO @tmp (data)
        SELECT [data]           
        FROM   [dbo].[stack] -- your table name here

        --Loop through all the records in temp table
        WHILE EXISTS (SELECT 1
                                    FROM   @tmp)            
            BEGIN 
                DECLARE @data VARCHAR(100) --Variable to chop up 
                DECLARE @data1 VARCHAR(100) -- Untouched variable to delete from tmp table
                SET @data =  (SELECT TOP 1 [data]
                                            FROM   @tmp)
                SET @data1 =  (SELECT TOP 1 [data]
                                             FROM   @tmp)

                --Loop through variable to get individual value 
                WHILE PATINDEX('%,%',@data) > 0     
                    BEGIN
                        INSERT INTO @tmp2
                        SELECT SUBSTRING(@data,1,PATINDEX('%,%',@data)-1);
                        SET @data = SUBSTRING(@data,PATINDEX('%,%',@data)+1,LEN(@data))
                        IF PATINDEX('%,%',@data) = 0
                            INSERT INTO @tmp2
                            SELECT @data            
                    END

                DELETE FROM @tmp 
                WHERE [data] = @data1

            END     

        SELECT * FROM @tmp2     
    END
于 2012-11-27T21:47:32.570 に答える
2

CTE を使用してデータを分割できます。

;with cte (DataItem, Data) as
(
  select cast(left(Data, charindex(',',Data+',')-1) as varchar(50)) DataItem,
         stuff(Data, 1, charindex(',',Data+','), '') Data
  from yourtable
  union all
  select cast(left(Data, charindex(',',Data+',')-1) as varchar(50)) DataItem,
    stuff(Data, 1, charindex(',',Data+','), '') Data
  from cte
  where Data > ''
) 
select DataItem
from cte

デモで SQL Fiddle を参照してください

結果:

| DATAITEM |
------------
|     1111 |
|       22 |
|       32 |
|       31 |
|       56 |
|       55 |
|       76 |
|       54 |
|       44 |
|      666 |
|       77 |

または、分割関数を作成できます。

create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX))       
as       
begin      
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return 
end;

クエリを実行するときにどちらを使用できますか。これにより、同じ結果が得られます。

select s.items declaration
from yourtable t1
outer apply dbo.split(t1.data, ',') s
于 2012-11-27T21:58:47.340 に答える
0

パフォーマンスについては話していませんが、データを 1 つの列に連結してから分割することができます。

データの連結: http://sqlfiddle.com/#!6/487a4/3

分割: T-SQL: 文字列連結の反対 - 文字列を複数のレコードに分割する方法

于 2012-11-27T19:50:32.043 に答える
0

同様の質問で参照されているこの記事を見てください。

http://www.codeproject.com/Articles/7938/SQL-User-Defined-Function-to-Parse-a-Delimited-Str

その記事にある関数を作成する場合は、次を使用して呼び出すことができます。

select * from dbo.fn_ParseText2Table('100|120|130.56|Yes|Cobalt Blue','|')

于 2012-11-27T21:36:14.760 に答える
0
SELECT REPLACE(field_name, ',', ' ') from table

編集:質問を変更したので、この回答は気にしないでください。

于 2012-11-27T17:38:02.453 に答える