كيفية - مبادئ قواعد البيانات sql
العثور على قيم مكررة في جدول SQL (16)
إذا كنت ترغب في حذف التكرارات ، فإليك طريقة أبسط بكثير للقيام بذلك من البحث عن صفوف زوجية / فردية في اختيار فرعي ثلاثي:
SELECT id, name, email
FROM users u, users u2
WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
وهكذا لحذف:
DELETE FROM users
WHERE id IN (
SELECT id/*, name, email*/
FROM users u, users u2
WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id
)
أسهل بكثير لقراءة وفهم IMHO
ملاحظة: المشكلة الوحيدة هي أنه يتعين عليك تنفيذ الطلب حتى لا يتم حذف صفوف ، نظرًا لأنك تقوم بحذف 1 فقط من كل تكرار في كل مرة
من السهل العثور على duplicates
حقل واحد:
SELECT name, COUNT(email)
FROM users
GROUP BY email
HAVING COUNT(email) > 1
لذلك إذا كان لدينا طاولة
ID NAME EMAIL
1 John [email protected]
2 Sam [email protected]
3 Tom [email protected]
4 Bob [email protected]
5 Tom [email protected]
سيقدم لنا هذا الاستفسار John، Sam، Tom، Tom لأنهم جميعًا لديهم نفس email
.
ومع ذلك ، ما أريده هو الحصول على نسخ مكررة باستخدام نفس email
name
.
هذا هو ، أريد الحصول على "توم" ، "توم".
السبب في أنني بحاجة إلى هذا: لقد ارتكبت خطأ ، وسمحت بإدخال name
مكرر وقيم email
. الآن أحتاج إلى إزالة / تغيير التكرارات ، لذا يجب أن أجدها أولاً.
إذا كنت ترغب في معرفة ما إذا كان هناك أي صفوف مكررة في جدولك ، فقد استخدمت أدناه طلب البحث:
create table my_table(id int, name varchar(100), email varchar(100));
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (2, 'Aman', '[email protected]');
insert into my_table values (3, 'Tom', '[email protected]');
insert into my_table values (4, 'Raj', '[email protected]');
Select COUNT(1) As Total_Rows from my_table
Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc
تأخرت قليلاً للحفل ولكنني وجدت حلًا رائعًا حقًا للعثور على جميع المكوّنات المكررة:
SELECT GROUP_CONCAT( id )
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )
جرب هذا الكود
WITH CTE AS
( SELECT Id, Name, Age, Comments, RN = ROW_NUMBER()OVER(PARTITION BY Name,Age ORDER BY ccn)
FROM ccnmaster )
select * from CTE
جرب هذا:
declare @YourTable table (id int, name varchar(10), email varchar(50))
INSERT @YourTable VALUES (1,'John','John-email')
INSERT @YourTable VALUES (2,'John','John-email')
INSERT @YourTable VALUES (3,'fred','John-email')
INSERT @YourTable VALUES (4,'fred','fred-email')
INSERT @YourTable VALUES (5,'sam','sam-email')
INSERT @YourTable VALUES (6,'sam','sam-email')
SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
انتاج:
name email CountOf
---------- ----------- -----------
John John-email 2
sam sam-email 2
(2 row(s) affected)
إذا كنت تريد استخدام معرفات الخوادم هذه:
SELECT
y.id,y.name,y.email
FROM @YourTable y
INNER JOIN (SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
) dt ON y.name=dt.name AND y.email=dt.email
انتاج:
id name email
----------- ---------- ------------
1 John John-email
2 John John-email
5 sam sam-email
6 sam sam-email
(4 row(s) affected)
لحذف النسخة المكررة ، حاول:
DELETE d
FROM @YourTable d
INNER JOIN (SELECT
y.id,y.name,y.email,ROW_NUMBER() OVER(PARTITION BY y.name,y.email ORDER BY y.name,y.email,y.id) AS RowRank
FROM @YourTable y
INNER JOIN (SELECT
name,email, COUNT(*) AS CountOf
FROM @YourTable
GROUP BY name,email
HAVING COUNT(*)>1
) dt ON y.name=dt.name AND y.email=dt.email
) dt2 ON d.id=dt2.id
WHERE dt2.RowRank!=1
SELECT * FROM @YourTable
انتاج:
id name email
----------- ---------- --------------
1 John John-email
3 fred John-email
4 fred fred-email
5 sam sam-email
(4 row(s) affected)
حاول القيام بما يلي:
SELECT * FROM
(
SELECT Id, Name, Age, Comments, Row_Number() OVER(PARTITION BY Name, Age ORDER By Name)
AS Rank
FROM Customers
) AS B WHERE Rank>1
كيف يمكننا حساب القيم المكررة؟ إما أنها تتكرر مرتين أو أكثر من 2. فقط عدّها ، وليس مجموعة حكيمة.
ببساطة
select COUNT(distinct col_01) from Table_01
هذا هو الشيء السهل الذي أتيت به يستخدم تعبير جدول شائع (CTE) ونافذة قسم (أعتقد أن هذه الميزات موجودة في SQL 2008 والإصدارات الأحدث).
يجد هذا المثال جميع الطلاب الذين لديهم اسم مكرر و dob. الحقول التي تريد التحقق من وجود تكرار لها في جملة OVER. يمكنك تضمين أي حقول أخرى تريدها في العرض.
with cte (StudentId, Fname, LName, DOB, RowCnt)
as (
SELECT StudentId, FirstName, LastName, DateOfBirth as DOB, SUM(1) OVER (Partition By FirstName, LastName, DateOfBirth) as RowCnt
FROM tblStudent
)
SELECT * from CTE where RowCnt > 1
ORDER BY DOB, LName
هذا يحدد / يحذف جميع السجلات المكررة باستثناء سجل واحد من كل مجموعة من التكرارات. لذلك ، يترك الحذف كل السجلات الفريدة + سجل واحد من كل مجموعة من التكرارات.
حدد التكرارات:
SELECT *
FROM table
WHERE
id NOT IN (
SELECT MIN(id)
FROM table
GROUP BY column1, column2
);
حذف التكرارات:
DELETE FROM table
WHERE
id NOT IN (
SELECT MIN(id)
FROM table
GROUP BY column1, column2
);
كن على دراية بكميات أكبر من السجلات ، يمكن أن يسبب مشاكل في الأداء.
SELECT column_name,COUNT(*) FROM TABLE_NAME GROUP BY column1, HAVING COUNT(*) > 1;
باستخدام CTE أيضا يمكننا أن نجد قيمة مكررة مثل هذا
with MyCTE
as
(
select Name,EmailId,ROW_NUMBER() over(PARTITION BY EmailId order by id) as Duplicate from [Employees]
)
select * from MyCTE where Duplicate>1
SELECT name, email
FROM users
WHERE email in
(SELECT email FROM users
GROUP BY email
HAVING COUNT(*)>1)
SELECT
name, email, COUNT(*)
FROM
users
GROUP BY
name, email
HAVING
COUNT(*) > 1
ببساطة مجموعة على كل من الأعمدة.
ملاحظة: معيار ANSI هو أن يكون جميع الأعمدة غير المجمعة في GROUP BY. يتيح لك MySQL تجنب هذا ، ولكن النتائج غير متوقعة:
- GROUP BY lname ORDER BY عرض نتائج خاطئة
- وهي أقل دالة تجميعية في غياب أي () (انظر التعليقات في الإجابة المقبولة)
في MySQL أنت بحاجة إلى sql_mode=only_full_group_by
SELECT
FirstName, LastName, MobileNo, COUNT(1) as CNT
FROM
CUSTOMER
GROUP BY
FirstName, LastName, MobileNo
HAVING
COUNT(1) > 1;
select id,name,COUNT(*) from India group by Id,Name having COUNT(*)>1
select name, email
, case
when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes'
else 'No'
end "duplicated ?"
from users