חלץ רק את הראשון מיחידת הרשומה שבה הערך של העמודה שצוינה משוכפל

עודכן דף :
תאריך יצירת דף :

בדרך כלל, כאשר מחלצים רק רשומה כפולה אחת, הדבר הראשון שעולה בראש הוא 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 כל שעליך לעשות הוא לקבל את השורה הראשונה של כל רשומה כפולה ב- .

במקור, זה בסדר, אבל אם יש שתי רשומות או יותר עם אותו ערך בדיוק, כגון "מזהה: 4, שם: שם 4@example.com", תקבל בהכרח שתי רשומות. row_number לכן, הוא מצורף כך שניתן יהיה לזהות אותו עבור כל שורה עם , כך שניתן יהיה לאחזר רק רשומה אחת עם אותו ערך בדיוק. אם ידוע כי אותה רשומה בדיוק אינה קיימת, אני row_number חושב שעדיף לבדוק את הערכים של הרשומות הקיימות מבלי לצרף .

אם יש לבדוק כפילויות במספר מפתחות, באפשרותך להגדיל את מספר עמודות המפתח עבור כל אחד מהם. לדוגמה, שקול את הרשומה הבאה: העמודות שיש לבדוק אם יש כפילויות הן "ID1" ו- "ID2".

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

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