Idealnya, solusi terbaik Anda adalah menormalkan Tabel2 sehingga Anda tidak menyimpan daftar yang dipisahkan koma.
Setelah data ini dinormalisasi, Anda dapat dengan mudah melakukan kueri data. Struktur tabel baru mungkin mirip dengan ini:
CREATE TABLE T1
(
[col1] varchar(2),
[col2] varchar(5),
constraint pk1_t1 primary key (col1)
);
INSERT INTO T1
([col1], [col2])
VALUES
('C1', 'john'),
('C2', 'alex'),
('C3', 'piers'),
('C4', 'sara')
;
CREATE TABLE T2
(
[col1] varchar(2),
[col2] varchar(2),
constraint pk1_t2 primary key (col1, col2),
constraint fk1_col2 foreign key (col2) references t1 (col1)
);
INSERT INTO T2
([col1], [col2])
VALUES
('R1', 'C1'),
('R1', 'C2'),
('R1', 'C4'),
('R2', 'C3'),
('R2', 'C4'),
('R3', 'C1'),
('R3', 'C4')
;
Menormalkan tabel akan memudahkan Anda untuk melakukan kueri data dengan menggabungkan tabel:
select t2.col1, t1.col2
from t2
inner join t1
on t2.col2 = t1.col1
Lihat Demo
Kemudian jika Anda ingin menampilkan data sebagai daftar yang dipisahkan koma, Anda dapat menggunakan FOR XML PATH
dan STUFF
:
select distinct t2.col1,
STUFF(
(SELECT distinct ', ' + t1.col2
FROM t1
inner join t2 t
on t1.col1 = t.col2
where t2.col1 = t.col1
FOR XML PATH ('')), 1, 1, '') col2
from t2;
Lihat Demo.
Jika Anda tidak dapat menormalkan data, maka ada beberapa hal yang dapat Anda lakukan.
Pertama, Anda dapat membuat fungsi split yang akan mengubah data yang disimpan dalam daftar menjadi baris yang dapat digabungkan. Fungsi split akan mirip dengan ini:
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;
Saat Anda menggunakan fungsi split, Anda dapat membiarkan data dalam beberapa baris atau Anda dapat menggabungkan nilai kembali ke dalam daftar yang dipisahkan koma:
;with cte as
(
select c.col1, t1.col2
from t1
inner join
(
select t2.col1, i.items col2
from t2
cross apply dbo.split(t2.col2, ',') i
) c
on t1.col1 = c.col2
)
select distinct c.col1,
STUFF(
(SELECT distinct ', ' + c1.col2
FROM cte c1
where c.col1 = c1.col1
FOR XML PATH ('')), 1, 1, '') col2
from cte c
Lihat Demo.
Cara terakhir agar Anda bisa mendapatkan hasilnya adalah dengan menerapkan FOR XML PATH
secara langsung.
select col1,
(
select ', '+t1.col2
from t1
where ','+t2.col2+',' like '%,'+cast(t1.col1 as varchar(10))+',%'
for xml path(''), type
).value('substring(text()[1], 3)', 'varchar(max)') as col2
from t2;
Lihat SQL Fiddle dengan Demo