আমার কাছে একটি ভারচার কলাম সহ একটি টেবিল রয়েছে এবং আমি এই কলামটিতে নকল মান রয়েছে এমন সমস্ত রেকর্ড সন্ধান করতে চাই। সদৃশগুলি সন্ধান করতে আমি সর্বোত্তম কোয়েরিটি কী ব্যবহার করতে পারি?
আমার কাছে একটি ভারচার কলাম সহ একটি টেবিল রয়েছে এবং আমি এই কলামটিতে নকল মান রয়েছে এমন সমস্ত রেকর্ড সন্ধান করতে চাই। সদৃশগুলি সন্ধান করতে আমি সর্বোত্তম কোয়েরিটি কী ব্যবহার করতে পারি?
উত্তর:
একটি কি 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
নকল রেকর্ডকে গোষ্ঠী করার সম্ভাবনা ।
ডুপ্লিকেট সারিগুলির আইডি পাওয়ার জন্য লেভিকের জবাব বন্ধ করে দেওয়া GROUP_CONCAT
যদি আপনি এটি করতে পারেন যে আপনার সার্ভার সমর্থন করে (এটি আইডির একটি কমা দ্বারা পৃথকীত তালিকা ফিরিয়ে দেবে)।
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
এটি ইনলাইন সম্পাদনা সক্ষম করে এবং এতে জড়িত সমস্ত সারিগুলি আপডেট করা উচিত (বা কমপক্ষে প্রথমটির সাথে মিলিত হওয়া) তবে দুর্ভাগ্যক্রমে সম্পাদনাটি জাভাস্ক্রিপ্ট ত্রুটি তৈরি করেছে। ..
ধরে নিলে আপনার টেবিলটির নাম টেবিলএবিসি এবং আপনি যে কলামটি চান সেটি করল এবং টি 1 এর প্রাথমিক কীটি কী is
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
উপরোক্ত উত্তরের উপর এই পদ্ধতির সুবিধাটি হ'ল এটি কী দেয়।
কর্মচারীর নাম কলামে কয়টি রেকর্ড নকল রয়েছে তা জানতে, নীচের ক্যোয়ারী সহায়ক;
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;
টেবিল নাম = আপনি যে টেবিলটির সাথে কাজ করছেন তা।
DupliactedData = ডুপ্লিকেট করা ডেটা আপনি সন্ধান করছেন।
আমার চূড়ান্ত ক্যোয়ারী এখানে কয়েকটি উত্তর অন্তর্ভুক্ত করেছে যা সহায়তা করেছে - গোষ্ঠী, গণনা এবং GROUP_CONCAT দ্বারা একত্রিত।
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
এটি উভয় উদাহরণের আইডি সরবরাহ করে (কমা পৃথকীর্ণ), আমার প্রয়োজন বারকোড এবং কতগুলি নকল।
সারণী এবং কলামগুলি সেই অনুযায়ী পরিবর্তন করুন।
আমি কোনও JOIN পন্থা দেখছি না, যার সদৃশ শর্তে অনেক ব্যবহার রয়েছে।
এই পদ্ধতির আপনাকে প্রকৃত দ্বিগুণ ফলাফল দেয়।
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 এর উত্তর উপরন্তু, আমি খুঁজে প্রয়োজন সব সারি যে ডুপ্লিকেট মান সঙ্গে ফিরে হয়েছিল, তাই আমি তাদের মধ্যে সম্পাদনা করতে পারে মাইএসকিউএল 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
সদৃশগুলি সন্ধান করতে আমি উইন্ডোড ফাংশনগুলি (মাইএসকিউএল 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
নীচে একাধিকবার ব্যবহৃত সমস্ত প্রোডাক্ট_আইডি খুঁজে পাবেন। আপনি প্রতিটি প্রোডাক্ট_আইডির জন্য কেবল একটি একক রেকর্ড পাবেন।
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
কোডটি নেওয়া হয়েছে: http : //ચેন্দরশানা.ব্লগস্পট.ইন.২০১৪ / ১২ / ফাইন্ড- ডুপ্লিকেট- রিকার্ডস-বেসড- অন-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.*
প্রায় তাত্ক্ষণিকভাবে সমাধানের জন্য এটি পরিবর্তন করা ।
একাধিক ক্ষেত্রের সাথে সদৃশ সারিগুলি অপসারণের জন্য, প্রথমে এগুলিকে নতুন স্বতন্ত্র কীতে ক্যানকেট করুন যা কেবলমাত্র পৃথক পৃথক সারিগুলির জন্য নির্দিষ্ট করা হয়েছে, তারপরে একই নতুন অনন্য কী দ্বারা সদৃশ সারিগুলি সরানোর জন্য "গ্রুপ বাই" কমান্ডটি ব্যবহার করুন:
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 ...
করবেন না ? আপনার সমাধানের একটি সামান্য ব্যাখ্যা দুর্দান্ত হবে।
একটি খুব দেরিতে অবদান ... যদি এটি কাউকে লাইনটি থেকে নামাতে সহায়তা করে ... একটি ব্যাংকিং অ্যাপে আমার সাথে একটি মিলের মিলের লেনদেনের (আসলে অ্যাকাউন্টে অ্যাকাউন্টে স্থানান্তরের উভয় পক্ষের) সন্ধান করার জন্য কোন কাজ ছিল, কোনটি সনাক্ত করতে প্রতিটি আন্তঃ-অ্যাকাউন্ট-স্থানান্তর লেনদেনের জন্য 'থেকে' এবং 'থেকে' ছিল, সুতরাং আমরা এটি দিয়ে শেষ করেছি:
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
নিশ্চিত হয়ে যায় যে দুটি ট্রানজিডিশনের ফলাফলগুলিতে সর্বদা একই ক্রমে থাকে, যা এটি GROUP
প্রথমটি দ্বারা নিরাপদ করে তোলে , এইভাবে সমস্ত নকল ম্যাচগুলি বাদ দেয়। প্রায় এক মিলিয়ন রেকর্ডের মধ্য দিয়ে দৌড়ে এবং মাত্র 2 সেকেন্ডের নীচে 12,000+ ম্যাচ সনাক্ত করে। অবশ্যই লেনদেন হল প্রাথমিক সূচক, যা সত্যই সহায়তা করেছিল।
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;