Tout d'abord, votre meilleure solution est de ne pas stocker les données dans une liste séparée par des virgules dans votre base de données. Vous devriez envisager de corriger la structure du tableau.
Si vous ne pouvez pas modifier la structure du tableau, vous devrez diviser les données de la liste en lignes pour attribuer le nom correct. Une fois les données divisées, vous pouvez concaténer les données dans la liste.
Il existe de nombreux split
différents fonction que vous pouvez trouver en ligne mais voici une version que j'utilise habituellement :
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;
Pour obtenir votre résultat, je commencerais par appliquer le split
fonction et un row_number()
car je ne vois pas de clé unique associée à chaque ligne. Si vous avez une clé unique sur chaque ligne, vous n'aurez pas besoin du row_number()
:
;with cte as
(
select rn, name, id
from
(
select row_number() over(order by (select 1)) rn,
databasename
from table2
) t2
cross apply dbo.split(t2.databasename, ',') i
inner join table1 t1
on i.items = t1.id
)
select *
from cte
Cette requête divise votre liste séparée par des virgules comme suit :
| RN | NAME | ID |
--------------------
| 1 | MSSQL | 1 |
| 1 | Oracle | 3 |
| 2 | MySQl | 2 |
| 3 | MSSQL | 1 |
| 3 | MySQl | 2 |
Une fois que vous avez les données dans plusieurs lignes avec le bon name
, alors vous pouvez utiliser STUFF()
et FOR XML PATH
pour le concaténer dans la liste. Votre requête complète ressemblerait à ceci :
;with cte as
(
select rn, name, id
from
(
select row_number() over(order by (select 1)) rn,
databasename
from table2
) t2
cross apply dbo.split(t2.databasename, ',') i
inner join table1 t1
on i.items = t1.id
)
select
STUFF(
(SELECT ', ' + c2.name
FROM cte c2
where c1.rn = c2.rn
order by c2.id
FOR XML PATH (''))
, 1, 1, '') Databasename
from cte c1
group by c1.rn
order by c1.rn;
Voir SQL Fiddle avec démo.
Le résultat de la requête complète est :
| DATABASENAME |
------------------
| MSSQL, Oracle |
| MySQl |
| MSSQL, MySQl |