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