แยกเฉพาะรายการแรกจากหน่วยระเบียนที่ค่าของคอลัมน์ที่ระบุซ้ํากัน

ปรับปรุงหน้า :
วันที่สร้างเพจ :

โดยปกติเมื่อแยกบันทึกที่ซ้ํากันเพียงแผ่นเดียวสิ่งแรกที่นึกถึงคือ 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

ไม่รวม ID 1 และ 2 เนื่องจากไม่ซ้ํากัน ID 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"

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