استخرج الأول فقط من وحدة السجل حيث يتم تكرار قيمة العمود المحدد

تحديث الصفحة :
تاريخ إنشاء الصفحة :

عادة ، عند استخراج سجل مكرر واحد فقط ، فإن أول ما يتبادر إلى الذهن هو 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 مكرران ، لذلك يتم استرداد أحدهما. ومع ذلك ، هذه المرة ، لن نحصل على السجل الأول في ترتيب تخزين DB. بالإضافة إلى ذلك ، افترض أنك تريد السطر الأول من الاسم بترتيب الأولوية بشروط أن "الاسم يحتوي على علامة @ " و "يحتوي الاسم على عدد قليل من الأحرف".

يمكن الحصول على الشرط أعلاه باستخدام 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 by تحديد ترتيب الأسبقية لاسترداد الصف الأول بواسطة . charindex هنا ، وتحقق len مما إذا كان يحتوي على الحرف المحدد وطول السلسلة. top كل ما عليك فعله هو الحصول على الصف الأول من كل سجل مكرر في .

في الأصل ، هذا جيد ، ولكن إذا كان هناك سجلان أو أكثر بنفس القيمة تماما ، مثل "ID: 4 ، Name: Name 4@example.com" ، فستحصل حتما على سجلين. row_number لذلك ، يتم إلحاقه بحيث يمكن تحديده لكل صف باستخدام ، بحيث يمكن استرداد سجل واحد فقط بنفس القيمة تماما. إذا كان من المعروف أن نفس السجل بالضبط غير موجود ، أعتقد row_number أنه سيكون من الأفضل التحقق من قيم السجلات الموجودة دون إلحاق.

إذا كانت هناك مفاتيح متعددة يجب التحقق منها بحثا عن التكرارات، فيمكنك زيادة عدد أعمدة المفاتيح لكل منها. على سبيل المثال، ضع في اعتبارك السجل التالي: الأعمدة التي سيتم التحقق منها بحثا عن التكرارات هي "ID1" و "ID2".

اسم ID1ID2
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

نتيجة الاستحواذ هي كما يلي.

اسم ID1ID2
4 2 الاسم 4@example.com
5 1 الاسم 55@example.com
6 1 الاسم 66@example.com
6 2 الاسم 6

تبدو SQL كما يلي: يمكنك ببساطة زيادة الجزء الذي تم تحديد عمود المفتاح فيه.

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