मेरे पास नीचे की तरह एक टेबल है, दो पते प्राथमिक और माध्यमिक हैं (कुछ एनआईडी में 3 पते हैं):

enter image description here

मुझे इसे नीचे की तरह एक पंक्ति में बदलने की जरूरत है:

enter image description here

मैं इस SQL ​​​​कथन को आजमाता हूं, लेकिन यह यादृच्छिक डेटा देता है।

SELECT 
    EnId, companyAddress, suite,city, state, zip,
    phoneNo, fax, emailId, country, primaryAddress
FROM   
    (SELECT 
         EnId, Value, field_name
     FROM   
         #ALLdata) src 
PIVOT 
    (MAX(Value)
         FOR field_name IN (companyAddress,suite, city.state, zip, PhoneNo,
                            fax, emailId, country, primaryAddress)
    ) pvt ; 

स्क्रिप्ट संलग्न करना:

CREATE TABLE [dbo].[Alldata](
[id] [bigint],
[EnId] [bigint] ,
[value] [nvarchar](max) ,
[field_name] [nvarchar](200))
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359691, 50052, N'123', N'suite')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359692, 50052, N'18', N'country')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359693, 50052, N'3025', N'state')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359694, 50052, N'30951', N'city')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359695, 50052, N'EC2A 4EG', N'zip')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359696, 50052, N'998-997-2050', N'phoneNo')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359698, 50052, N'info@asite.com', N'emailId')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359699, 50052, N'true', N'primaryAddress')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359701, 50052, N'Test data', N'companyAddress')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359702, 50052, N'Test222', N'suite')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359703, 50052, N'108', N'country')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359704, 50052, N'85', N'state')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359705, 50052, N'5', N'city')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359706, 50052, N'', N'zip')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359707, 50052, N'562151256126', N'phoneNo')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359709, 50052, N'shfagsdhbf@gmail.com', N'emailId')
INSERT [dbo].[Alldata] ([id], [EnId], [value], [field_name]) VALUES (359710, 50052, N'false', N'primaryAddress');

0
Gaurang Prajapati 22 मार्च 2021, 08:28

2 जवाब

सबसे बढ़िया उत्तर

यह मानते हुए कि आपके पास पते के प्रत्येक सेट के लिए लापता पंक्ति नहीं होगी, आप पते के प्रत्येक सेट की पहचान करने के लिए एक संख्या उत्पन्न करने के लिए row_number() over (partition by field_name order by id) का उपयोग कर सकते हैं।

एक बार आपके पास यह हो जाने के बाद, आप पिवोटिंग करने के लिए कंडीशनल केस के साथ एग्रीगेट का उपयोग कर सकते हैं।

WITH
data AS
(
    SELECT *, addr_no = row_number() over (partition by field_name order by id)
    FROM   dbo.Alldata
)
SELECT EnId,
       MAX(CASE WHEN field_name = 'companyAddress' THEN value END) AS companyAddress,
       MAX(CASE WHEN field_name = 'suite' THEN value END) AS suite,
       MAX(CASE WHEN field_name = 'city' THEN value END) AS city,
       MAX(CASE WHEN field_name = 'state' THEN value END) AS state,
       . . . .
FROM   data
GROUP BY EnId, addr_no

डीबीफिलडे डेमो

2
Squirrel 22 मार्च 2021, 09:36

यह एक सिरदर्द है, क्योंकि जैसा कि मैंने टिप्पणियों में उल्लेख किया है, आप पतों को अलग करने के लिए पंक्तियों के क्रम पर भरोसा कर रहे हैं। हमें पहले किसी ऐसे कॉलम की आवश्यकता होगी जो किसी पते की सभी पंक्तियों के लिए समान हो लेकिन प्रत्येक पते के लिए अलग हो। शायद यह:

SELECT *, 
  ENID * 100 +
  SUM(CASE WHEN field_name = 'companyAddress' THEN 1 ELSE 0 END) OVER (PARTITION BY Enid ORDER BY id) as Enid_addr
FROM #alldata

अब आपको एक enid_addr कॉलम दिखना चाहिए जो पहले पते के लिए 5005201 जैसा है, दूसरे के लिए 5005202 है, और आप उस पर पिवट कर सकते हैं

यह कैसे काम करता है:

  • हम फ़ील्ड नाम को देखने के लिए एक केस का उपयोग करते हैं और 1 देते हैं यदि यह कंपनी पता पंक्ति (किसी विशेष पते के लिए लिखी गई पहली पंक्ति) है, अन्यथा 0, तो आप एक कॉलम के साथ समाप्त होंगे जो सभी 1 था और 0, कंपनी के पते के लिए केवल 1 ही 1
  • फिर हम इस पर योग करते हैं, और डिफ़ॉल्ट रूप से एक योग प्रारंभ (सबसे कम आईडी वाला एक ही एनिड) और वर्तमान पंक्ति के बीच प्रत्येक पंक्ति को जोड़ता है। असल में इसका मतलब है कि पहले पते वाली सभी पंक्तियों को 1,1,1,1 मिलता है, क्योंकि पहली पंक्ति के लिए यह 1 है, दूसरी पंक्ति 1+0 है, तीसरी पंक्ति 1+0+0 है और इसी तरह। और फिर जब आप कंपनी के पते की दूसरी घटना को हिट करते हैं, तो अचानक 2 (1+0+0..+1) होता है, फिर यह अगली सभी पंक्तियों के लिए 2 होता है जब तक कि आप किसी अन्य कंपनी के पते को हिट नहीं करते, तब यह 3
  • यदि हम Enid लेते हैं और इसे 100 से गुणा करते हैं और फिर इस काउंटर को जोड़ते हैं तो इसका मतलब है कि अब Enid प्रति पता अद्वितीय है, इसका पहला N अंक पुराना Enid है और फिर अंतिम दो पता संख्या दे रहा है। यदि आपके पास प्रति व्यक्ति 99 से अधिक पते हैं, तो इसके बजाय एक हजार से गुणा करें आदि

अब आपके पास वह डेटा है जिसे आप इस नए एनिड पर पिवट कर सकते हैं और आपकी सामग्री अब मिश्रित नहीं होगी

इसे अपनी क्वेरी में फिट करने के लिए, बीच में जहां आपके पास SELECT Enid, value, fieldname है, Enid को (ENID * 100) + SUM(CASE WHEN field_name = 'companyAddress' THEN 1 ELSE 0 END) OVER (PARTITION BY Enid ORDER BY id) as Enid से बदलें

ध्यान दें कि आपको इससे अपना वांछित परिणाम बिल्कुल नहीं मिलेगा: यह 50053 के बजाय 5005202 जैसा दिखेगा। यदि आप 50053 चाहते हैं, और आप पूरी तरह से सुनिश्चित हैं कि आपके पास तालिका में कहीं और 50053 नहीं है एक टक्कर का कारण बनता है, आप * 100 को हटाने के लिए तर्क को समायोजित कर सकते हैं, और एसयूएम() ओवर() के अंत में -1 डाल सकते हैं ताकि आप पहले पते के लिए 0 जोड़ रहे हों, दूसरे के लिए 1 आदि।

हालाँकि मैं आपसे ऐसा करने के लिए विनती करता हूँ जैसा मैंने और गिलहरी ने टिप्पणियों में पूछा और। तालिका में सम्मिलित प्रोग्राम को फिर से डिज़ाइन करें। जब तक आपने इसे कोडित नहीं किया है, तब तक कोई संभावित तरीका नहीं है कि प्राथमिक पता डालने से द्वितीयक पता सम्मिलित हो जाएगा, आप पंक्तियों के क्रम पर भरोसा नहीं कर सकते हैं। इंसर्टिंग करने वाला प्रोग्राम आसानी से Enid+एक और कॉलम बना सकता है जो प्रति एड्रेस अद्वितीय है; बस दूसरे कॉलम को एक काउंटर इंट बनाएं जो 1 से शुरू होता है और प्रति पता सहेजा जाता है या यदि विभिन्न मशीनें एक साथ प्राथमिक और द्वितीयक पते लिखती हैं, तो प्रत्येक मशीन पर एक गाइड अलग होगा

2
Caius Jard 22 मार्च 2021, 09:20