2011-02-25 15 views
20

मुझे एक कॉलम मान को एकाधिक कॉलम मानों में विभाजित करने में समस्या है।एक कॉलम मानों को एकाधिक कॉलम मानों में कैसे विभाजित करें?

उदाहरण के लिए:

Name 
------------ 
abcd efgh 
ijk lmn opq 
asd j. asdjja 
asb (asdfas) asd 
asd 

और मैं इस तरह उत्पादन कुछ चाहिए:

first_name    last_name 
---------------------------------- 
abcd      efgh 
ijk      opq 
asd      asdjja 
asb      asd 
asd      null 

मध्य नाम छोड़ा जा सकता है (एक मध्य नाम की कोई आवश्यकता नहीं) कॉलम पहले से ही बनाई गई हैं और उस एकल Name कॉलम से डेटा डालने की आवश्यकता है।

+0

क्या आप SQL सर्वर के भीतर ऐसा करना चाहते हैं? एक 'चयन' कथन में? 'INSERT' या 'UPDATE' कथन में? अधिक जानकारी हमें आपके प्रश्न – BinaryTox1n

+0

का उत्तर देने में मदद करेगी जो कि नाम भंडारण के लिए भयानक डिज़ाइन है, आपको पहले, आखिरी, मध्य नाम को अलग-अलग कॉलम के रूप में रखने पर विचार करना चाहिए, मुझे आशा है कि आप इस तालिका से कोई भी रिपोर्ट नहीं करेंगे जो नामों को विभाजित करता है जैसा आपने अनुरोध किया था –

+0

एक चयन कथन में इसकी आवश्यकता है। असल में यह संग्रहित प्रक्रिया के लिए है जो तालिका से मूल्यों का चयन करके डेटा डालने वाला है। इसलिए मुझे इसे चुनिंदा कथन में मिलता है जो बहुत अच्छा होगा ... – Shahsra

उत्तर

18

आपका दृष्टिकोण सही ढंग से नामों में से बहुत कुछ के साथ सौदा नहीं होगा, लेकिन ...

SELECT CASE 
     WHEN name LIKE '% %' THEN LEFT(name, Charindex(' ', name) - 1) 
     ELSE name 
     END, 
     CASE 
     WHEN name LIKE '% %' THEN RIGHT(name, Charindex(' ', Reverse(name)) - 1) 
     END 
FROM YourTable 
+0

मुझे त्रुटि मिलती है: # 1305 - फ़ंक्शन प्रीप्रोडेम। चेरिन्डेक्स मौजूद नहीं है। कुछ खोज के बाद मैंने पाया कि यह फ़ंक्शन mysql द्वारा समर्थित नहीं है, और इसे हल करने के लिए SUBSTRING_INDEX का उपयोग करके कुछ बदलावों की आवश्यकता है। – Mimouni

+2

@IlyasMimouni - यह सवाल SQL सर्वर टैग किया गया है। –

2

आपको जो चाहिए वह एक विभाजित उपयोगकर्ता-परिभाषित फ़ंक्शन है। इसी के साथ, समाधान लग रहा है

With SplitValues As 
    (
    Select T.Name, Z.Position, Z.Value 
     , Row_Number() Over (Partition By T.Name Order By Z.Position) As Num 
    From Table As T 
     Cross Apply dbo.udf_Split(T.Name, ' ') As Z 
    ) 
Select Name 
    , FirstName.Value 
    , Case When ThirdName Is Null Then SecondName Else ThirdName End As LastName 
From SplitValues As FirstName 
    Left Join SplitValues As SecondName 
     On S2.Name = S1.Name 
      And S2.Num = 2 
    Left Join SplitValues As ThirdName 
     On S2.Name = S1.Name 
      And S2.Num = 3 
Where FirstName.Num = 1 

यहां नमूने के विभाजन समारोह है जैसे:

Create Function [dbo].[udf_Split] 
( 
    @DelimitedList nvarchar(max) 
    , @Delimiter nvarchar(2) = ',' 
) 
RETURNS TABLE 
AS 
RETURN 
    (
    With CorrectedList As 
     (
     Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End 
      + @DelimitedList 
      + Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End 
      As List 
      , Len(@Delimiter) As DelimiterLen 
     ) 
     , Numbers As 
     (
     Select TOP(Coalesce(DataLength(@DelimitedList)/2,0)) Row_Number() Over (Order By c1.object_id) As Value 
     From sys.columns As c1 
      Cross Join sys.columns As c2 
     ) 
    Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position 
     , Substring (
        CL.List 
        , CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen  
        , CharIndex(@Delimiter, CL.list, N.Value + 1)       
         - (CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen) 
        ) As Value 
    From CorrectedList As CL 
     Cross Join Numbers As N 
    Where N.Value <= DataLength(CL.List)/2 
     And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter 
    ) 
13

एक मार्टिन के

select LEFT(name, CHARINDEX(' ', name + ' ') -1), 
     STUFF(name, 1, Len(Name) +1- CHARINDEX(' ',Reverse(name)), '') 
from somenames 

नमूना के विकल्प तालिका

create table somenames (Name varchar(100)) 
insert somenames select 'abcd efgh' 
insert somenames select 'ijk lmn opq' 
insert somenames select 'asd j. asdjja' 
insert somenames select 'asb (asdfas) asd' 
insert somenames select 'asd' 
insert somenames select '' 
insert somenames select null 
+0

तो यह क्वेरी उस कॉलम में लाखों मानों के लिए काम करती है जो मुझे लगता है .... – Shahsra

+1

@ शाहसरा - हां। परिभाषा के अनुसार एसक्यूएल एक एसईटी-आधारित भाषा है, इसलिए आप एक रिकॉर्ड पर जो भी करते हैं, वह सभी रिकॉर्डों पर समान रूप से किया जाता है .. – RichardTheKiwi

+0

ऐसा लगता है कि इस समय केवल दो बार का नाम दें? –

2
;WITH Split_Names (Name, xmlname) 
AS 
(
    SELECT 
    Name, 
    CONVERT(XML,'<Names><name>' 
    + REPLACE(Name,' ', '</name><name>') + '</name></Names>') AS xmlname 
     FROM somenames 
) 

SELECT  
xmlname.value('/Names[1]/name[1]','varchar(100)') AS first_name,  
xmlname.value('/Names[1]/name[2]','varchar(100)') AS last_name 
FROM Split_Names 

और यह भी संदर्भ के लिए नीचे दिए गए लिंक की जाँच

http://jahaines.blogspot.in/2009/06/converting-delimited-string-of-values.html

0

यहाँ है मैं कैसे एक SQLite डेटाबेस पर ऐसा किया:

SELECT SUBSTR(name, 1,INSTR(name, " ")-1) as Firstname, SUBSTR(name, INSTR(name," ")+1, LENGTH(name)) as Lastname FROM YourTable;

यह आशा है कि मदद करता है.

0
SELECT 
    SUBSTRING_INDEX(SUBSTRING_INDEX(rent, ' ', 1), ' ', -1) AS currency, 
    SUBSTRING_INDEX(SUBSTRING_INDEX(rent, ' ', 3), ' ', -1) AS rent 
FROM tolets 
संबंधित मुद्दे