Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर 2008 में स्प्लिट फ़ंक्शन

सबसे पहले, आपका सबसे अच्छा समाधान है कि आप अपने डेटाबेस में अल्पविराम से अलग की गई सूची में डेटा संग्रहीत न करें। आपको टेबल संरचना को ठीक करने पर विचार करना चाहिए।

यदि आप तालिका संरचना में परिवर्तन नहीं कर सकते हैं, तो आपको सही नाम निर्दिष्ट करने के लिए सूची में डेटा को पंक्तियों में विभाजित करना होगा। एक बार डेटा विभाजित हो जाने पर आप डेटा को सूची में वापस जोड़ सकते हैं।

कई अलग-अलग हैं split फ़ंक्शन जिसे आप ऑनलाइन पा सकते हैं लेकिन यहां एक ऐसा संस्करण है जिसका मैं आमतौर पर उपयोग करता हूं:

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;

आपका परिणाम प्राप्त करने के लिए, मैं split . लागू करके शुरू करूंगा फ़ंक्शन और एक row_number() चूंकि मुझे प्रत्येक पंक्ति से जुड़ी एक अनूठी कुंजी दिखाई नहीं दे रही है। यदि आपके पास प्रत्येक पंक्ति पर एक अद्वितीय कुंजी है तो आपको 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

यह क्वेरी आपकी अल्पविराम से अलग की गई सूची को निम्न में विभाजित करती है:

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

एक बार जब आपके पास सही name . के साथ कई पंक्तियों में डेटा हो , तो आप STUFF() . का उपयोग कर सकते हैं और FOR XML PATH इसे सूची में शामिल करने के लिए। आपकी पूरी क्वेरी कुछ इस तरह होगी:

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

डेमो के साथ SQL Fiddle देखें।

पूरी क्वेरी का परिणाम है:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर में त्रुटि संदेश 7325 को कैसे ठीक करें:"वितरित प्रश्नों में CLR प्रकार वाले स्तंभों को उजागर करने वाली वस्तुओं की अनुमति नहीं है"

  2. SQL सर्वर में महीने के नाम को महीने की संख्या में बदलें

  3. मैं अपने स्थानीय विकास सर्वर पर SQL Azure डेटाबेस की प्रतिलिपि कैसे बना सकता हूँ?

  4. SQL सर्वर में सम्मिलित करने का प्रयास करते समय "वर्चर मान को परिवर्तित करते समय रूपांतरण विफल" ठीक करें

  5. SQL सर्वर (T-SQL) में फ़ोन नंबर प्रारूपित करें