একটি এসকিউএল সারণীতে সদৃশ মান সন্ধান করা


1931

একটি ক্ষেত্রের সাথে সদৃশগুলি পাওয়া সহজ:

SELECT name, COUNT(email) 
FROM users
GROUP BY email
HAVING COUNT(email) > 1

সুতরাং আমরা একটি টেবিল আছে

ID   NAME   EMAIL
1    John   asd@asd.com
2    Sam    asd@asd.com
3    Tom    asd@asd.com
4    Bob    bob@asd.com
5    Tom    asd@asd.com

এই ক্যোয়ারীটি আমাদের জন, স্যাম, টম, টম দেবে কারণ তাদের সকলেরই রয়েছে email

তবে কি আমি চাই একই সঙ্গে সদৃশ পেতে হয় email এবং name

অর্থাৎ আমি "টম", "টম" পেতে চাই।

আমার এটির কারণ: আমি একটি ভুল করেছি, এবং সদৃশ nameএবং emailমান সন্নিবেশ করার অনুমতি দিয়েছি । এখন আমার ডুপ্লিকেটগুলি মুছে ফেলার / পরিবর্তন করা দরকার, তাই আমার এটি প্রথমে সন্ধান করা উচিত।


28
আমি মনে করি না যে এটি আপনার প্রথম নমুনায় নাম নির্বাচন করতে দেয় কারণ এটি একটি সামগ্রিক কার্যক্রমে নয়। "মেইল ইমেল ঠিকানা এবং তাদের নাম গণনা কি" কিছু জটিল যুক্তি ...
এসএক্স

3
পাওয়া গেছে যে nameনির্বাচনটিতে ক্ষেত্রের কারণে এটি এমএসএসকিউএল সার্ভারের সাথে কাজ করে না ।
ই ভ্যান পুটেন

আমার যা দরকার তা হ'ল নকল ইমেল সহ রেকর্ডগুলির আইডি
মার্কোস ডি পাওলো

উত্তর:


3034
SELECT
    name, email, COUNT(*)
FROM
    users
GROUP BY
    name, email
HAVING 
    COUNT(*) > 1

উভয় কলামে কেবল গ্রুপ করুন।

দ্রষ্টব্য: পুরানো এএনএসআই স্ট্যান্ডার্ডটি হ'ল গ্রুপের মাধ্যমে সমস্ত অ-একত্রিত কলাম থাকা কিন্তু এটি "কার্যকরী নির্ভরতা" ধারণার সাথে পরিবর্তিত হয়েছে :

রিলেশনাল ডাটাবেস তত্ত্বে, একটি কার্যকরী নির্ভরতা হ'ল ডেটাবেস থেকে সম্পর্কের ক্ষেত্রে দুটি সেট বৈশিষ্ট্যের মধ্যে একটি সীমাবদ্ধতা। অন্য কথায়, কার্যকরী নির্ভরতা একটি সীমাবদ্ধতা যা কোনও সম্পর্কের বৈশিষ্ট্যের মধ্যে সম্পর্ককে বর্ণনা করে।

সমর্থন সামঞ্জস্যপূর্ণ নয়:


92
@ ওয়েবেএক্সএল যেখানে একক রেকর্ডের সাথে কাজ করছে গ্রুপের সাথে কাজ করছে
বিজন

8
@gbn ফলাফলগুলিতে আইডি অন্তর্ভুক্ত করা কি সম্ভব? তারপরে সেই নকলগুলি মুছে ফেলা সহজ হবে be
ব্যবহারকারী 797717

13
@ ব্যবহারকারী 77 777717১17: আপনার এমআইএন (আইডি) থাকা দরকার এবং তারপরে আইডি মানগুলির জন্য মুছে ফেলতে হবে যদি মিন (আইডি) মানগুলি না হয়
gbn

1
যে কোনও ক্ষেত্রে কলামগুলির নাল মান রয়েছে সেগুলি সম্পর্কে কী বলা যায়?
অঙ্কিত ধীঙ্গরা

1
এর জন্য আপনাকে অনেক ধন্যবাদ, এবং হ্যাঁ এটি ওরাকল-এ কাজ করে, যদিও আমার শর্তটির স্বাতন্ত্র্য প্রয়োজন, তার চেয়ে বরং>1 =1
বিল নায়লর

370

এটা চেষ্টা কর:

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)


72

আপনি যদি সদৃশগুলি মুছতে চান তবে ট্রিপল সাব-সিলেক্টে এমনকি বিজোড় সারিগুলি সন্ধান করার চেয়ে এটি করার সহজ উপায় এখানে:

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
)

আইএমএইচও পড়তে এবং বুঝতে আরও অনেক সহজ

দ্রষ্টব্য: একমাত্র ইস্যুটি হ'ল কোনও অনুরূপ সারি মুছে না দেওয়া পর্যন্ত আপনাকে অনুরোধটি সম্পাদন করতে হবে, কারণ আপনি প্রতি বারে প্রতিটি নকলের মধ্যে কেবল 1 টি মুছবেন


2
সুন্দর এবং পড়া সহজ; আমি এমন একটি উপায় খুঁজতে চাই যা একসাথে একাধিক সদৃশ সারি মুছে ফেলে।
ডিকন রিড

1
আমি যেমন পাই You can't specify target table 'users' for update in FROM clause
তেমনটি

1
: @Whitecat একটি সহজ মাইএসকিউএল সমস্যা মত মনে হয় stackoverflow.com/questions/4429319/...
AncAinu

1
আমার জন্য ব্যর্থ। আমি পেয়েছি: "ডিবিডি :: সিএসভি :: এসটি এক্সিকিউট ব্যর্থ হয়েছে: / ইউজারস / হর্নেঞ্জ / স্পেরল 5 / স্পারব্রিব / স্পার্লস / স্পেক 5-26.0/lib/site_perl/5.26 এ হ্যাশ উপাদানটিতে অবিচ্ছিন্ন মান value _ [1] এর ব্যবহার। 0 / এসকিউএল / ইভাল.এমপি লাইন 43 "
নাইজেল হর্ন

1
আমি মনে করি যে যেখানে ক্লজটি "u.name = u2.name এবং u.email = u2.email এবং" (u.id> u2.id বা u2.id> u.id) হওয়া উচিত তাই না?

48

নিম্নলিখিত চেষ্টা করুন:

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

3
নির্বাচন করুন * এ সামান্য পরিবর্তন আমাকে এক ঘন্টা অনুসন্ধানে সহায়তা করেছে। আমি আগে কখনও ওভার (পার্টিশন এর আগে কখনও ব্যবহার করি নি
S


28

পার্টিতে কিছুটা দেরি হলেও আমি সমস্ত নকল আইডি খুঁজে পেতে খুব শীতল কাজ পেয়েছি:

SELECT GROUP_CONCAT( id )
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )

2
চারপাশে সিন্টেক্সটিকাল চিনির কাজ বলে মনে হচ্ছে। ভাল লাগছে।
শেফ_কোড

3
মনে রাখবেন যে GROUP_CONCATকিছু পূর্ব নির্ধারিত দৈর্ঘ্যের পরে থামবে, যাতে আপনি সমস্ত idগুলি নাও পেতে পারেন ।
v010dya


23

এটি নকলের প্রতিটি গ্রুপের একটি রেকর্ড বাদে সমস্ত সদৃশ রেকর্ড নির্বাচন / মুছে ফেলে। সুতরাং, মুছুন অনুলিপি প্রতিটি গ্রুপ থেকে সমস্ত অনন্য রেকর্ড + একটি রেকর্ড ছেড়ে।

সদৃশ নির্বাচন করুন:

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

বৃহত পরিমাণে রেকর্ড সম্পর্কে সচেতন থাকুন, এটি কার্য সম্পাদনের সমস্যা তৈরি করতে পারে।


2
কোয়েরি মোছার ক্ষেত্রে ত্রুটি - আপনি FROM ধারাটিতে আপডেটের জন্য লক্ষ্য টেবিল 'শহরগুলি' নির্দিষ্ট করতে পারবেন না
আলী আজহার

2
টেবিলের 'শহরগুলি' বা আপডেট ধারা নেই। আপনি কি বোঝাতে চেয়েছেন? মোছা ক্যোয়ারিতে ত্রুটি কোথায়?
মার্টিন সিলোভস্ক

2
ওপির ডেটা দিয়ে কীভাবে এটি কাজ করে?
thoroc

3
"ওপি" এর অর্থ কী?
মার্টিন সিলভস্কý

19

আপনি যদি ওরাকল এর সাথে কাজ করেন তবে এই উপায়টি পছন্দনীয় হবে:

create table my_users(id number, name varchar2(100), email varchar2(100));

insert into my_users values (1, 'John', 'asd@asd.com');
insert into my_users values (2, 'Sam', 'asd@asd.com');
insert into my_users values (3, 'Tom', 'asd@asd.com');
insert into my_users values (4, 'Bob', 'bob@asd.com');
insert into my_users values (5, 'Tom', 'asd@asd.com');

commit;

select *
  from my_users
 where rowid not in (select min(rowid) from my_users group by name, email);

15
select name, email
, case 
when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes'
else 'No'
end "duplicated ?"
from users

2
কোড উত্তর কেবল স্ট্যাক ওভারফ্লোতে নকল করা হয়, আপনি ব্যাখ্যা করতে পারেন কেন এই প্রশ্নের উত্তর?
ধনী বেনার

2
@ রিচবেনার: ফলাফল হিসাবে প্রতিটি এবং প্রতিটি সারির মতো প্রতিক্রিয়া আমি খুঁজে পাইনি এবং যা আমাদের জানায় যেগুলি সমস্ত সদৃশ সারি এবং কোন এক নজরে নয় এবং এটির দ্বারা দলবদ্ধ না করা, কারণ যদি আমরা এটি একত্রিত করতে চাই দ্বারা অন্য কোনও কোয়েরি গ্রুপের সাথে কোয়েরি করা ভাল বিকল্প নয়।
নরেন্দ্র

2
নির্বাচিত বিবৃতিতে আইডি যুক্ত করা এবং নকল করাতে ফিল্টারিং, এটি আপনাকে সদৃশ আইডিগুলি মুছে ফেলার সম্ভাবনা দেয় এবং প্রতিটিটিতে রেখে দেয়।
এন্টোইন রিইনহোল্ড বার্ট্র্যান্ড

12

যদি আপনি দেখতে চান যে আপনার টেবিলে কোনও নকল সারি রয়েছে কিনা, আমি কোয়েরির নীচে ব্যবহার করেছি:

create table my_table(id int, name varchar(100), email varchar(100));

insert into my_table values (1, 'shekh', 'shekh@rms.com');
insert into my_table values (1, 'shekh', 'shekh@rms.com');
insert into my_table values (2, 'Aman', 'aman@rms.com');
insert into my_table values (3, 'Tom', 'tom@rms.com');
insert into my_table values (4, 'Raj', 'raj@rms.com');


Select COUNT(1) As Total_Rows from my_table 
Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc 

11

এটি আমি নিয়ে এসেছি এমন সহজ জিনিস। এটি একটি সাধারণ টেবিল এক্সপ্রেশন (সিটিই) এবং একটি পার্টিশন উইন্ডো ব্যবহার করে (আমি মনে করি এই বৈশিষ্ট্যগুলি এসকিউএল ২০০৮ এবং তার পরে রয়েছে)।

এই উদাহরণটি সদৃশ নাম এবং ডাব সহ সমস্ত ছাত্রকে খুঁজে পায়। নকলকরণের জন্য আপনি যে ক্ষেত্রগুলি পরীক্ষা করতে চান সেগুলি ওভার ক্লজে চলে যায়। অভিক্ষেপে আপনি চাইলে অন্য যে কোনও ক্ষেত্র অন্তর্ভুক্ত করতে পারেন।

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


10

আমরা কীভাবে নকল মান গণনা করতে পারি ?? হয় এটি 2 বার বা 2 এরও বেশি বার পুনরাবৃত্তি হয় কেবল তাদের গণনা করুন, গোষ্ঠী অনুসারে নয়।

মতই সহজ

select COUNT(distinct col_01) from Table_01

2
জিজ্ঞাসা করা প্রশ্ন হিসাবে এই কাজ করবে? এটি বিভিন্ন সারিগুলিতে একাধিক কলামে (যেমন "ইমেল" এবং "নাম") নকল তথ্য সারণী দেয় না ows
জেরোইন

10

সিটিই ব্যবহার করেও আমরা এর মতো সদৃশ মানটি পেতে পারি

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

9
 select emp.ename, emp.empno, dept.loc 
          from emp
 inner join dept 
          on dept.deptno=emp.deptno
 inner join
    (select ename, count(*) from
    emp
    group by ename, deptno
    having count(*) > 1)
 t on emp.ename=t.ename order by emp.ename
/

7

SELECT id, COUNT(id) FROM table1 GROUP BY id HAVING COUNT(id)>1;

আমি মনে করি এটি নির্দিষ্ট কলামে পুনরাবৃত্ত মানগুলি সন্ধান করতে সঠিকভাবে কাজ করবে।


6
এটি শীর্ষের উত্তরে পুরোপুরি কিছু যুক্ত করে না এবং প্রযুক্তিগতভাবে এমনকি প্রশ্নটিতে পোস্ট করা ওপি-র কোড থেকে সত্যই আলাদা নয়।
জেরোইন

7
SELECT * FROM users u where rowid = (select max(rowid) from users u1 where
u.email=u1.email);

6

এটিও কাজ করা উচিত, চেষ্টা করে দেখুন।

  Select * from Users a
            where EXISTS (Select * from Users b 
                where (     a.name = b.name 
                        OR  a.email = b.email)
                     and a.ID != b.id)

বিশেষত আপনার ক্ষেত্রে ভাল আপনি যদি ডুপ্লিকেটগুলির সন্ধান করেন যাঁর কোনও ধরণের উপসর্গ বা সাধারণ পরিবর্তন আছে যেমন মেলটিতে নতুন ডোমেন। তারপরে আপনি এই কলামগুলিতে প্রতিস্থাপন () ব্যবহার করতে পারেন


5

আপনি যদি সদৃশ ডেটা (এক বা একাধিক মাপদণ্ডের দ্বারা) সন্ধান করতে চান এবং আসল সারিগুলি নির্বাচন করুন।

with MYCTE as (
    SELECT DuplicateKey1
        ,DuplicateKey2 --optional
        ,count(*) X
    FROM MyTable
    group by DuplicateKey1, DuplicateKey2
    having count(*) > 1
) 
SELECT E.*
FROM MyTable E
JOIN MYCTE cte
ON E.DuplicateKey1=cte.DuplicateKey1
    AND E.DuplicateKey2=cte.DuplicateKey2
ORDER BY E.DuplicateKey1, E.DuplicateKey2, CreatedAt

http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/


4
SELECT name, email,COUNT(email) 
FROM users 
WHERE email IN (
    SELECT email 
    FROM users 
    GROUP BY email 
    HAVING COUNT(email) > 1)

আপনি COUNTছাড়া এটি ব্যবহার করতে পারবেন না GROUP BY, যদি না এটি পুরো টেবিলটিকে বোঝায়।
রালফ্রেডল

গোষ্ঠী ব্যতীত আপনি COUNT ব্যবহার করেছেন তবে এখানে আমি লিখতে টাইপ করতে ভুল করেছি
মোহাম্মদ নিমুল ইসলাম

3

যার নামগুলি নকল records

;WITH CTE AS    
(

    SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS T FROM     @YourTable    
)

DELETE FROM CTE WHERE T > 1

3

একটি সারণীতে সদৃশ রেকর্ড থেকে পরীক্ষা করতে।

select * from users s 
where rowid < any 
(select rowid from users k where s.name = k.name and s.email = k.email);

অথবা

select * from users s 
where rowid not in 
(select max(rowid) from users k where s.name = k.name and s.email = k.email);

কোনও সারণীতে সদৃশ রেকর্ড মুছতে।

delete from users s 
where rowid < any 
(select rowid from users k where s.name = k.name and s.email = k.email);

অথবা

delete from users s 
where rowid not in 
(select max(rowid) from users k where s.name = k.name and s.email = k.email);


1

নীচে প্রদর্শিত হিসাবে সামগ্রিক ফাংশনগুলিতে কাজ করে যা আমরা এখানে থাকার ব্যবহার করতে পারি

create table #TableB (id_account int, data int, [date] date)
insert into #TableB values (1 ,-50, '10/20/2018'),
(1, 20, '10/09/2018'),
(2 ,-900, '10/01/2018'),
(1 ,20, '09/25/2018'),
(1 ,-100, '08/01/2018')  

SELECT id_account , data, COUNT(*)
FROM #TableB
GROUP BY id_account , data
HAVING COUNT(id_account) > 1

drop table #TableB

এখানে দুটি ক্ষেত্র হিসাবে id_account এবং ডেটা গণনা (*) এর সাথে ব্যবহৃত হয়। সুতরাং, এটি সমস্ত রেকর্ড দেবে যা উভয় কলামে একাধিকবার একই মান রয়েছে।

আমরা কোনও কারণে ভুল করে এসকিউএল সার্ভার সারণীতে কোনও বাধা যুক্ত করতে মিস করেছি এবং রেকর্ডগুলি সামনের-শেষ অ্যাপ্লিকেশন সহ সমস্ত কলামে নকল .োকানো হয়েছে। তারপরে আমরা টেবিল থেকে সদৃশ ক্যোয়ারী মুছতে নীচের ক্যোয়ারীটি ব্যবহার করতে পারি।

SELECT DISTINCT * INTO #TemNewTable FROM #OriginalTable
TRUNCATE TABLE #OriginalTable
INSERT INTO #OriginalTable SELECT * FROM #TemNewTable
DROP TABLE #TemNewTable

এখানে আমরা অরিনগাল টেবিলের সমস্ত স্বতন্ত্র রেকর্ড নিয়েছি এবং মূল সারণীর রেকর্ডগুলি মুছে ফেলেছি। আবার আমরা নতুন টেবিল থেকে মূল টেবিলে সমস্ত স্বতন্ত্র মান andোকালাম এবং তারপরে নতুন টেবিলটি মুছলাম।


1

আপনি এটি চেষ্টা করতে পারেন

SELECT NAME, EMAIL, COUNT(*)
FROM USERS
GROUP BY 1,2
HAVING COUNT(*) > 1

1

এখানে সর্বাধিক গুরুত্বপূর্ণ বিষয়টি হল দ্রুততম কাজ। নকলের সূচকগুলিও সনাক্ত করা উচিত। স্ব জোড় করা একটি ভাল বিকল্প তবে একটি দ্রুত কাজ করার জন্য প্রথমে নকল রয়েছে এমন সারিগুলি সন্ধান করা এবং তারপরে নকল করা সারিগুলির আইডি সন্ধানের জন্য মূল টেবিলের সাথে যুক্ত হওয়া ভাল। একে অপরের কাছে সদৃশ সারি থাকা আইডি ব্যতীত যে কোনও কলামের মাধ্যমে অর্ডার করুন।

SELECT u.*
FROM users AS u
JOIN (SELECT username, email
      FROM users
      GROUP BY username, email
      HAVING COUNT(*)>1) AS w
ON u.username=w.username AND u.email=w.email
ORDER BY u.email;

0

সদৃশতা থেকে মুক্তি পেতে আপনি SELECT DISTINCT কীওয়ার্ডটি ব্যবহার করতে পারেন। আপনি নাম অনুসারেও ফিল্টার করতে পারেন এবং প্রত্যেককে একটি টেবিলে সেই নামটি দিয়ে পেতে পারেন।


0

আপনি নকল সারি পাশাপাশি সন্ধান করতে চান বা একই ইমেল এবং নাম সহ কেবল ভিন্ন আইডির উপর নির্ভর করে সঠিক কোডটি পৃথক হবে। আইডি যদি প্রাথমিক কী বা অন্যথায় একটি অনন্য বাধা থাকে তবে এই পার্থক্যটি বিদ্যমান নেই, তবে প্রশ্নটি এটি নির্দিষ্ট করে না। আগের ক্ষেত্রে আপনি অন্য কয়েকটি উত্তরে প্রদত্ত কোড ব্যবহার করতে পারেন:

SELECT name, email, COUNT(*)
FROM users
GROUP BY name, email
HAVING COUNT(*) > 1

পরবর্তী ক্ষেত্রে আপনি ব্যবহার করবেন:

SELECT name, email, COUNT(DISTINCT id)
FROM users
GROUP BY name, email
HAVING COUNT(DISTINCT id) > 1
ORDER BY COUNT(DISTINCT id) DESC
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.