web-dev-qa-db-ja.com

列に基づいて「グループ解除」データ

SQL Server 2012を使用していて、Id列とPseudoId列を含むテーブルAと、興味のない他の束を持っています。私が興味を持っているのは、特にPseudoIdです。このPseudoIdは特定の形式である必要がありますが、1つの問題があります。セミコロンで区切られた同じ行に複数のPseudoIdが存在する可能性があります。

1つのPseudoIdのLIKEステートメントを作成する方法はすでに理解しましたが、次のクエリを作成するのに問題があります。したがって、1の場合、これは簡単ですが、もう少しトリッキーです。

テーブルAを「グループ解除」して、新しいテーブルAを返すようにしなければならないと思っていました。次の条件が当てはまります。行にPseudoIdが1つしかない場合は、その行を返します。そうでない場合は、セミコロンで行を分割し、行を返します。これらはすべて同じですが、PseudoIdが異なります。

だから例えば:

ID | PseudoId  
-------------  
 1 | ABC  
 2 | DEF  
 3 | GHI;JKL  
 4 | MNO  
 5 | PQR;STU;VWX  

これを「グループ解除」すると、次のようになります。

ID | PseudoId  
-------------  
 1 | ABC  
 2 | DEF  
 3 | GHI  
 3 | JKL  
 4 | MNO  
 5 | PQR  
 5 | STU  
 5 | VWX  

私はおそらくテーブル値関数を使用するでしょうが、これを達成する方法は完全にはわかりません...

2

これはTVFで実行できます。SQLServer 2016以降に移行する場合は、STRING_SPLITを使用できます。

関数のソース: https://stackoverflow.com/questions/10914576/t-sql-split-string

( '、'の代わりに ';'を使用するように少し変更されました)

関数の作成

CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX(';', @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(';', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END

テストデータ

CREATE TABLE test(id int, pseudoid varchar(255))
insert into test 
values(1 ,'ABC'),
(2 ,'DEF'),
(3 ,'GHI;JKL'),
(4, 'MNO'),
(5 ,'PQR;STU;VWX')

[〜#〜]テスト[〜#〜]

   select id , s.Name as PseudoID from
    test 
    cross apply dbo.splitstring(pseudoid) as s

[〜#〜]結果[〜#〜]

id  PseudoID 
1   ABC
2   DEF
3   GHI
3   JKL
4   MNO
5   PQR
5   STU
5   VWX
1
Randi Vertongen