रिकॉर्ड इकाई से केवल पहले एक को निकालें जहां निर्दिष्ट कॉलम का मान डुप्लिकेट किया गया है

पेज अद्यतन :
पेज निर्माण की तारीख :

आम तौर पर, केवल एक डुप्लिकेट रिकॉर्ड निकालते समय, पहली बात जो दिमाग में आती है वह है मुझे लगता है distinct , distinct आपको एक डुप्लिकेट कॉलम और अन्य कॉलम निर्दिष्ट करने की अनुमति नहीं देता है जिसे आप एक ही समय में पुनर्प्राप्त करना चाहते हैं। इसके अतिरिक्त,distinct इस आवश्यकता से मेल नहीं खाता क्योंकि इसमें निष्कर्षण में गैर-डुप्लिकेट रिकॉर्ड शामिल हैं.

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

आईडी नाम
1 नाम 1
2 नाम 2
3 नाम 3
3 नाम 3@example.com
4 नाम 4 नाम 4@example.com
4 नाम 4@example.com
4 नाम 4@example.com

इसे इस प्रकार प्राप्त करें:

आईडी नाम
3 नाम 3@example.com
4 नाम 4@example.com

आईडी 1 और 2 शामिल नहीं हैं क्योंकि वे डुप्लिकेट नहीं हैं। आईडी 3 और 4 डुप्लिकेट हैं, इसलिए उनमें से एक को पुनर्प्राप्त किया गया है। हालांकि, इस बार हमें डीबी स्टोरेज ऑर्डर में पहला रिकॉर्ड नहीं मिलेगा। इसके अलावा, मान लें कि आप शर्तों के तहत प्राथमिकता के क्रम में नाम की पहली पंक्ति चाहते हैं कि "नाम में @ चिह्न है" और "नाम में वर्णों की एक छोटी संख्या है"।

उपरोक्त स्थिति निम्नलिखित SQL के साथ प्राप्त की जा सकती है। हालाँकि, हम सबक्वेरी का उपयोग कर रहे हैं और प्रदर्शन की जाँच नहीं की है।

select
  *
from
  (select *, row_number() over(order by ID asc) as RowNum from SampleTable) tableMain
where tableMain.RowNum =
(
  select
    top(1) RowNum
  from
    (select *, row_number() over(order by ID asc) as RowNum from SampleTable) tableSub
  where
        tableMain.ID = tableSub.ID
    and exists ( 
      select
        *
      from
        SampleTable
      where
        tableSub.ID = ID
      having
        count(*) >= 2
    )
  order by
    case when charindex(N'@', Name) >= 1 then 0 else 1 end, len(Name)
)

डुप्लिकेट पंक्तियों के साथ जाँच की जाती है having और count . group by कुंजी कॉलम को बाहर से जांचा जाना है, यहां ID कॉलम को संकुचित किया गया है where

पहली पंक्ति को पुनः प्राप्त करने के लिए वरीयता का क्रम निर्दिष्ट किया गया है order bycharindex यहां, और len जांचें कि क्या इसमें निर्दिष्ट वर्ण और स्ट्रिंग की लंबाई है। top आपको बस इतना करना है कि प्रत्येक डुप्लिकेट रिकॉर्ड की पहली पंक्ति .

मूल रूप से, यह ठीक है, लेकिन अगर बिल्कुल समान मूल्य वाले दो या अधिक रिकॉर्ड हैं, जैसे "आईडी: 4, नाम: नाम 4@example.com", तो आपको अनिवार्य रूप से दो रिकॉर्ड मिलेंगे। row_number इसलिए, इसे जोड़ा जाता है ताकि इसे प्रत्येक पंक्ति के लिए पहचाना जा सके, ताकि ठीक उसी मान वाला केवल एक रिकॉर्ड पुनर्प्राप्त किया जा सके। यदि यह ज्ञात है कि सटीक समान रिकॉर्ड मौजूद नहीं है, तो मुझे row_number लगता है कि मौजूदा रिकॉर्ड के मूल्यों को बिना संलग्न किए जांचना बेहतर होगा।

यदि डुप्लिकेट के लिए जाँचने के लिए एकाधिक कुंजियाँ हैं, तो आप प्रत्येक के लिए कुंजी स्तंभों की संख्या बढ़ा सकते हैं. उदाहरण के लिए, निम्न रिकॉर्ड पर विचार करें: डुप्लिकेट के लिए चेक किए जाने वाले कॉलम "आईडी 1" और "आईडी 2" हैं।

ID1 ID2 नाम
1 1 नाम 1
2 1 नाम 2
3 1 नाम 31
3 2 नाम 32
4 1 नाम41
4 2 नाम42
4 2 नाम 4@example.com
5 1 नाम 555@example.com
5 1 नाम 55@example.com
5 2 नाम 5@example.com
6 1 नाम 6
6 1 नाम 66@example.com
6 2 नाम 6
6 2 नाम 6

अधिग्रहण परिणाम इस प्रकार है।

ID1 ID2 नाम
4 2 नाम 4@example.com
5 1 नाम 55@example.com
6 1 नाम 66@example.com
6 2 नाम 6

एसक्यूएल इस तरह दिखता है: आप बस उस हिस्से को बढ़ा सकते हैं जहां कुंजी कॉलम निर्दिष्ट किया गया था।

select
  *
from
  (select *, row_number() over(order by ID1 asc, ID2 asc) as RowNum from SampleTable) tableMain
where tableMain.RowNum =
(
  select
    top(1) RowNum
  from
    (select *, row_number() over(order by ID1 asc, ID2 asc) as RowNum from SampleTable) tableSub
  where
        tableMain.ID1 = tableSub.ID1
    and tableMain.ID2 = tableSub.ID2
    and exists ( 
      select
        *
      from
        SampleTable
      where
            tableSub.ID1 = ID1
        and tableSub.ID2 = ID2
      having
        count(*) >= 2
    )
  order by
    case when charindex(N'@', Name) >= 1 then 0 else 1 end, len(Name)
)