เลือกคำสั่งเพื่อค้นหารายการซ้ำในบางฟิลด์


415

คุณสามารถช่วยฉันด้วยคำสั่ง SQL เพื่อค้นหารายการที่ซ้ำกันในหลายสาขาได้หรือไม่?

ตัวอย่างเช่นในรหัสเทียม:

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

และจากคำสั่งดังกล่าวหากมีเกิดขึ้นหลายฉันต้องการจะเลือกบันทึกทุกยกเว้นคนแรก


3
รหัสเทียมของคุณไม่ชัดเจนและคุณไม่ได้กำหนดลำดับตามที่คุณไม่ต้องการเป็นอันดับแรก ฉันขอแนะนำให้คุณให้ข้อมูลตัวอย่าง
ไม่มีเหตุผล

คำตอบ:


840

ในการรับรายการเขตข้อมูลที่มีหลายระเบียนคุณสามารถใช้ ..

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

ตรวจสอบลิงค์นี้สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการลบแถว

http://support.microsoft.com/kb/139444

แก้ไข: ตามที่ผู้ใช้รายอื่นกล่าวถึงควรมีเกณฑ์สำหรับการตัดสินใจว่าคุณกำหนด "แถวแรก" ก่อนที่คุณจะใช้วิธีการในลิงก์ด้านบน ขึ้นอยู่กับว่าคุณจะต้องใช้คำสั่งซื้อตามข้อและแบบสอบถามย่อยหากจำเป็น ถ้าคุณสามารถโพสต์ข้อมูลตัวอย่างมันจะช่วยได้จริงๆ


42

คุณพูดถึง "คนแรก" ดังนั้นฉันคิดว่าคุณมีการสั่งซื้อข้อมูลของคุณ สมมติว่าข้อมูลของคุณถูกสั่งซื้อในบางฟิลด์IDสมมติว่าข้อมูลของคุณจะได้รับคำสั่งจากข้อมูลบางส่วน

SQL นี้ควรให้คุณได้รับรายการที่ซ้ำกันยกเว้นรายการแรก โดยทั่วไปจะเลือกแถวทั้งหมดที่อีกแถวหนึ่งที่มี (a) เขตข้อมูลเดียวกันและ (b) มีรหัสที่ต่ำกว่า ประสิทธิภาพจะไม่ดีนัก แต่อาจช่วยแก้ปัญหาของคุณได้

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

17

นี่เป็นโซลูชันที่สนุกสำหรับ SQL Server 2005 ที่ฉันชอบ ฉันจะสมมติว่าโดย "สำหรับทุกเรคคอร์ดยกเว้นอันแรก" คุณหมายความว่ามีอีกคอลัมน์ "id" ที่เราสามารถใช้เพื่อระบุแถวที่เป็น "แรก"

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

เพิ่งสังเกตเห็นแท็ก SQL Server 2008 ดีใจที่คำแนะนำของฉันยังคงใช้ได้
Nick Vaccaro

1
วิธีแก้ปัญหาที่ยอดเยี่ยมเพราะมันจะส่งคืนแถวที่จะต้องถูกลบออกจากตารางที่มีปัญหา
Realto619

1
ช่วยให้คิดถึงการแบ่งพาร์ติชันตามรายการฟิลด์เป็นรายการของฟิลด์ PK
bkwdesign


3

หากคุณใช้ SQL Server 2005 หรือใหม่กว่า (และแท็กสำหรับคำถามของคุณระบุว่า SQL Server 2008) คุณสามารถใช้ฟังก์ชั่นการจัดอันดับเพื่อส่งกลับระเบียนที่ซ้ำกันหลังจากหนึ่งรายการแรกหากใช้การรวมเป็นที่ต้องการน้อยกว่าหรือไม่สามารถทำได้ ตัวอย่างต่อไปนี้แสดงสิ่งนี้ในทางปฏิบัติซึ่งยังใช้งานได้กับค่า Null ในคอลัมน์ที่ตรวจสอบ

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

โปรดสังเกตว่าหลังจากเรียกใช้ตัวอย่างนี้ว่ามีการยกเว้นระเบียนแรกของ "กลุ่ม" ทุกกลุ่มและมีการจัดการระเบียนที่มีค่า Null อย่างถูกต้อง

หากคุณไม่มีคอลัมน์ให้เรียงลำดับระเบียนภายในกลุ่มคุณสามารถใช้คอลัมน์แยกตามพาร์ติชันเป็นคอลัมน์เรียงลำดับตาม


1
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    

0

ลองเคียวรีนี้เพื่อให้ sepratley มีจำนวนของแต่ละคำสั่ง SELECT:

select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.