ฉันมีตารางที่มีคอลัมน์ varchar และฉันต้องการค้นหาระเบียนทั้งหมดที่มีค่าซ้ำกันในคอลัมน์นี้ แบบสอบถามที่ดีที่สุดที่ฉันสามารถใช้เพื่อค้นหารายการที่ซ้ำกันคืออะไร
ฉันมีตารางที่มีคอลัมน์ varchar และฉันต้องการค้นหาระเบียนทั้งหมดที่มีค่าซ้ำกันในคอลัมน์นี้ แบบสอบถามที่ดีที่สุดที่ฉันสามารถใช้เพื่อค้นหารายการที่ซ้ำกันคืออะไร
คำตอบ:
ทำSELECT
ด้วยGROUP BY
ประโยค สมมติว่าชื่อคือคอลัมน์ที่คุณต้องการค้นหารายการที่ซ้ำกันใน:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
สิ่งนี้จะส่งคืนผลลัพธ์ที่มีค่าชื่อในคอลัมน์แรกและนับจำนวนครั้งที่ค่านั้นปรากฏในวินาที
GROUP_CONCAT(id)
และมันจะแสดงรายการรหัส ดูคำตอบของฉันสำหรับตัวอย่าง
ERROR: column "c" does not exist LINE 1
?
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
IN()
NOT IN()
SELECT *
FROM mytable mto
WHERE EXISTS
(
SELECT 1
FROM mytable mti
WHERE mti.varchar_column = mto.varchar_column
LIMIT 1, 1
)
แบบสอบถามนี้ส่งกลับระเบียนที่สมบูรณ์ไม่ได้เป็นเพียงที่แตกต่างกันvarchar_column
ของ
COUNT(*)
แบบสอบถามนี้ไม่ได้ใช้ หากมีจำนวนมากซ้ำCOUNT(*)
มีราคาแพงและคุณไม่ต้องการทั้งหมดCOUNT(*)
คุณเพียงแค่ต้องรู้ว่ามีสองแถวที่มีค่าเท่ากันหรือไม่
แน่นอนว่าการมีดัชนีตามvarchar_column
ประสงค์จะทำให้การสืบค้นนี้รวดเร็วขึ้น
ORDER BY varchar_column DESC
ในส่วนท้ายของแบบสอบถาม
GROUP BY
และHAVING
ส่งกลับรายการที่ซ้ำซ้อนเพียงรายการเดียว นอกจากนี้ประสิทธิภาพการทำงานที่มีเขตข้อมูลที่จัดทำดัชนีแทนCOUNT(*)
และความเป็นไปได้ที่ORDER BY
จะจัดกลุ่มระเบียนที่ซ้ำกัน
การสร้างคำตอบของ levik เพื่อรับ ID ของแถวที่ซ้ำกันที่คุณสามารถทำได้GROUP_CONCAT
หากเซิร์ฟเวอร์ของคุณรองรับ (จะเป็นการคืนรายการรหัส id ที่คั่นด้วยเครื่องหมายจุลภาค)
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
จะเปิดใช้งานการแก้ไขแบบอินไลน์และควรอัพเดตแถวทั้งหมดที่เกี่ยวข้อง (หรืออย่างน้อยหนึ่งอันแรกที่ตรงกัน) แต่น่าเสียดายที่การแก้ไขสร้างข้อผิดพลาด Javascript ..
สมมติว่าตารางของคุณชื่อ TableABC และคอลัมน์ที่คุณต้องการคือ Col และคีย์หลักของ T1 คือ Key
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
ข้อได้เปรียบของวิธีการนี้เหนือคำตอบข้างต้นคือให้คีย์
SELECT *
FROM `dps`
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
หากต้องการค้นหาจำนวนระเบียนที่ซ้ำกันในคอลัมน์ชื่อในพนักงานแบบสอบถามด้านล่างมีประโยชน์
Select name from employee group by name having count(*)>1;
เพื่อรับข้อมูลทั้งหมดที่มีการทำซ้ำฉันใช้สิ่งนี้:
SELECT * FROM TableName INNER JOIN(
SELECT DupliactedData FROM TableName GROUP BY DupliactedData HAVING COUNT(DupliactedData) > 1 order by DupliactedData)
temp ON TableName.DupliactedData = temp.DupliactedData;
TableName = ตารางที่คุณทำงานด้วย
DupliactedData = ข้อมูลซ้ำซ้อนที่คุณกำลังมองหา
ข้อความค้นหาสุดท้ายของฉันรวมคำตอบสองสามข้อไว้ที่นี่ซึ่งช่วย - รวมกลุ่มโดยนับ & GROUP_CONCAT
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
สิ่งนี้แสดงรหัสของทั้งสองตัวอย่าง (คั่นด้วยเครื่องหมายจุลภาค), บาร์โค้ดที่ฉันต้องการและจำนวนซ้ำ
เปลี่ยนตารางและคอลัมน์ตาม
ฉันไม่เห็นวิธีการเข้าร่วมใด ๆ ซึ่งมีประโยชน์หลายประการในแง่ของการทำซ้ำ
วิธีการนี้ให้ผลลัพธ์ที่แท้จริงสองเท่า
SELECT t1.* FROM my_table as t1
LEFT JOIN my_table as t2
ON t1.name=t2.name and t1.id!=t2.id
WHERE t2.id IS NOT NULL
ORDER BY t1.name
SELECT t.*,(select count(*) from city as tt
where tt.name=t.name) as count
FROM `city` as t
where (
select count(*) from city as tt
where tt.name=t.name
) > 1 order by count desc
แทนที่เมืองด้วยตารางของคุณ แทนที่ชื่อด้วยชื่อฟิลด์ของคุณ
การ@ maxyfc ของคำตอบต่อไปผมต้องการที่จะหาทุกแถวที่ได้กลับมาพร้อมกับค่าที่ซ้ำกันดังนั้นฉันสามารถแก้ไขได้ในMySQL Workbench :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
ฉันเห็นผลลัพธ์ข้างต้นและแบบสอบถามจะทำงานได้ดีถ้าคุณต้องการตรวจสอบค่าคอลัมน์เดียวซึ่งซ้ำกัน ตัวอย่างอีเมล
แต่ถ้าคุณต้องการตรวจสอบกับคอลัมน์เพิ่มเติมและต้องการตรวจสอบการรวมกันของผลลัพธ์ดังนั้นแบบสอบถามนี้จะทำงานได้ดี:
SELECT COUNT(CONCAT(name,email)) AS tot,
name,
email
FROM users
GROUP BY CONCAT(name,email)
HAVING tot>1 (This query will SHOW the USER list which ARE greater THAN 1
AND also COUNT)
SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
ฉันชอบใช้ฟังก์ชั่นแบบมีหน้าต่าง (MySQL 8.0+) เพื่อค้นหารายการที่ซ้ำกันเพราะฉันเห็นทั้งแถว:
WITH cte AS (
SELECT *
,COUNT(*) OVER(PARTITION BY col_name) AS num_of_duplicates_group
,ROW_NUMBER() OVER(PARTITION BY col_name ORDER BY col_name2) AS pos_in_group
FROM table
)
SELECT *
FROM cte
WHERE num_of_duplicates_group > 1;
SELECT
t.*,
(SELECT COUNT(*) FROM city AS tt WHERE tt.name=t.name) AS count
FROM `city` AS t
WHERE
(SELECT count(*) FROM city AS tt WHERE tt.name=t.name) > 1 ORDER BY count DESC
ต่อไปนี้จะค้นหา product_id ทั้งหมดที่ใช้มากกว่าหนึ่งครั้ง คุณจะได้รับบันทึกเดียวสำหรับแต่ละ product_id
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
รหัสที่นำมาจาก: http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on-any.html
CREATE TABLE tbl_master
(`id` int, `email` varchar(15));
INSERT INTO tbl_master
(`id`, `email`) VALUES
(1, 'test1@gmail.com'),
(2, 'test2@gmail.com'),
(3, 'test1@gmail.com'),
(4, 'test2@gmail.com'),
(5, 'test5@gmail.com');
QUERY : SELECT id, email FROM tbl_master
WHERE email IN (SELECT email FROM tbl_master GROUP BY email HAVING COUNT(id) > 1)
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
a.email
ไปa.*
และได้รับรหัสทั้งหมดของแถวที่มีรายการที่ซ้ำกัน
SELECT DISTINCT a.*
แก้ไขเกือบจะทันที
สำหรับการลบแถวที่ซ้ำกันที่มีหลายฟิลด์ให้ยกเลิกไปที่คีย์เฉพาะใหม่ซึ่งระบุไว้สำหรับแถวที่ต่างกันเท่านั้นจากนั้นใช้คำสั่ง "group by" เพื่อลบแถวที่ซ้ำกันด้วยคีย์เฉพาะใหม่ที่เหมือนกัน:
Create TEMPORARY table tmp select concat(f1,f2) as cfs,t1.* from mytable as t1;
Create index x_tmp_cfs on tmp(cfs);
Create table unduptable select f1,f2,... from tmp group by cfs;
CREATE TEMPORARY TABLE ...
? คำอธิบายเล็ก ๆ ของการแก้ปัญหาของคุณจะดีมาก
การบริจาคล่าช้ามาก ... ในกรณีที่มันช่วยให้ทุกคน waaaaaay ลงเส้น ... ฉันมีงานหาคู่ที่ตรงกันของธุรกรรม (อันที่จริงทั้งสองด้านของการถ่ายโอนระหว่างบัญชีกับบัญชี) ในแอพธนาคารเพื่อระบุว่าอันไหน คือ 'จาก' และ 'ถึง' สำหรับธุรกรรมการโอนเงินระหว่างบัญชีแต่ละรายการดังนั้นเราจึงได้ทำสิ่งนี้:
SELECT
LEAST(primaryid, secondaryid) AS transactionid1,
GREATEST(primaryid, secondaryid) AS transactionid2
FROM (
SELECT table1.transactionid AS primaryid,
table2.transactionid AS secondaryid
FROM financial_transactions table1
INNER JOIN financial_transactions table2
ON table1.accountid = table2.accountid
AND table1.transactionid <> table2.transactionid
AND table1.transactiondate = table2.transactiondate
AND table1.sourceref = table2.destinationref
AND table1.amount = (0 - table2.amount)
) AS DuplicateResultsTable
GROUP BY transactionid1
ORDER BY transactionid1;
ผลที่ได้คือDuplicateResultsTable
ให้แถวที่มีการจับคู่ธุรกรรม (เช่นซ้ำกัน) แต่มันก็ให้รหัสธุรกรรมเดียวกันในสิ่งที่ตรงกันข้ามในครั้งที่สองที่ตรงกับคู่เดียวกันดังนั้นด้านนอกSELECT
จะจัดกลุ่มตามรหัสธุรกรรมแรกซึ่งเสร็จสิ้นแล้ว โดยใช้LEAST
และGREATEST
เพื่อให้แน่ใจว่าทั้งสอง transactionid อยู่ในลำดับเดียวกันเสมอในผลลัพธ์ซึ่งทำให้ปลอดภัยGROUP
โดยรายการแรกจึงกำจัดการแข่งขันที่ซ้ำกันทั้งหมด ขับรถผ่านเกือบหนึ่งล้านบันทึกและระบุการแข่งขันกว่า 12,000 รายการภายในเวลาเพียง 2 วินาที แน่นอนว่า transactionid เป็นดัชนีหลักซึ่งช่วยได้จริงๆ
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
หากคุณต้องการลบการใช้ซ้ำ DISTINCT
มิฉะนั้นใช้แบบสอบถามนี้:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
ลองใช้แบบสอบถามนี้:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;