Idealiter zou uw beste oplossing zijn om Tabel 2 te normaliseren, zodat u geen door komma's gescheiden lijst opslaat.
Zodra u deze gegevens hebt genormaliseerd, kunt u de gegevens eenvoudig opvragen. De nieuwe tabelstructuur zou er ongeveer zo uit kunnen zien:
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')
;
Het normaliseren van de tabellen zou het voor u veel gemakkelijker maken om de gegevens op te vragen door de tabellen samen te voegen:
select t2.col1, t1.col2
from t2
inner join t1
on t2.col2 = t1.col1
Zie demo
Als u vervolgens de gegevens als een door komma's gescheiden lijst wilt weergeven, kunt u FOR XML PATH
gebruiken en 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;
Zie demo.
Als u de gegevens niet kunt normaliseren, zijn er verschillende dingen die u kunt doen.
Ten eerste zou u een splitsingsfunctie kunnen maken die de gegevens die in de lijst zijn opgeslagen, omzet in rijen die kunnen worden samengevoegd. De splitsingsfunctie zou er ongeveer zo uitzien:
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;
Wanneer u de functie Splitsen gebruikt, kunt u de gegevens in de meerdere rijen laten staan of u kunt de waarden weer samenvoegen in een door komma's gescheiden lijst:
;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
Zie demo.
Een laatste manier om het resultaat te krijgen is door FOR XML PATH
toe te passen rechtstreeks.
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;
Zie SQL Fiddle met demo