sql >> Database >  >> RDS >> Sqlserver

Splitfunctie in SQL Server 2008

Ten eerste is uw beste oplossing om gegevens niet op te slaan in een door komma's gescheiden lijst in uw database. U kunt overwegen de tabelstructuur te corrigeren.

Als u de tabelstructuur niet kunt wijzigen, moet u de gegevens in de lijst in rijen splitsen om de juiste naam toe te wijzen. Zodra de gegevens zijn gesplitst, kunt u de gegevens weer samenvoegen in de lijst.

Er zijn veel verschillende split functie die u online kunt vinden, maar hier is een versie die ik meestal gebruik:

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;

Om uw resultaat te krijgen, zou ik beginnen met het toepassen van de split functie en een row_number() omdat ik geen unieke sleutel zie die aan elke rij is gekoppeld. Als je een unieke sleutel op elke rij hebt, heb je de row_number() niet nodig :

;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

Deze zoekopdracht verdeelt uw door komma's gescheiden lijst als volgt:

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

Zodra u de gegevens in meerdere rijen heeft met de juiste name , dan kun je STUFF() . gebruiken en FOR XML PATH om het in de lijst samen te voegen. Je volledige zoekopdracht zou er ongeveer zo uitzien:

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

Zie SQL Fiddle met demo.

Het resultaat van de volledige zoekopdracht is:

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


  1. Verwijderen met Join in MySQL

  2. Hoe panda's dataframe via mysqldb in de database invoegen?

  3. Een gebruiker in Superuser veranderen in PostgreSQL

  4. Uw MySQL-installatie beveiligen