sql >> Database teknologi >  >> RDS >> Sqlserver

Split funktion i SQL Server 2008

For det første er din bedste løsning ikke at gemme data i en kommasepareret liste i din database. Du bør overveje at rette tabelstrukturen.

Hvis du ikke kan ændre tabelstrukturen, bliver du nødt til at opdele dataene på listen i rækker for at tildele det korrekte navn. Når dataene er opdelt, kan du sammenkæde dataene tilbage til listen.

Der er mange forskellige split funktion, som du kan finde online, men her er en version, som jeg typisk bruger:

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;
 

For at få dit resultat, ville jeg starte med at anvende split funktion og en row_number() da jeg ikke kan se en unik nøgle forbundet med hver række. Hvis du har en unik nøgle på hver række, behøver du ikke 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

Denne forespørgsel opdeler din kommaseparerede liste i følgende:

| RN | NAME | ID | -------------------- | 1 | MSSQL | 1 | | 1 | Oracle | 3 | | 2 | MySQl | 2 | | 3 | MSSQL | 1 | | 3 | MySQl | 2 |

Når du har dataene i flere rækker med det korrekte name , så kan du bruge STUFF() og FOR XML PATH at sammenkæde det i listen. Din fulde forespørgsel ville ligne denne:

;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;

Se SQL Fiddle with Demo.

Resultatet af den fulde forespørgsel er:

| DATABASENAME | ------------------ | MSSQL, Oracle | | MySQl | | MSSQL, MySQl |

  1. Sådan håndteres BOB-undtagelser

  2. returnere værdi ved en position fra STRING_SPLIT i SQL Server 2016

  3. Hvordan indsætter jeg flere værdier i en postgres-tabel på én gang?

  4. Upload CSV-fil til SQL-server