كيفية العثور على التكرارات في عمودين وليس 1

StackOverflow https://stackoverflow.com/questions/642656

  •  22-07-2019
  •  | 
  •  

سؤال

لدي جدول قاعدة بيانات MySQL يحتوي على عمودين يثيران اهتمامي.بشكل فردي، يمكن أن يكون لكل منهما نسخ مكررة، لكن لا ينبغي أبدًا أن يكون لديهما نسخة مكررة من كل منهما لهما نفس القيمة.

stone_id يمكن أن يكون لها نسخ مكررة طالما لكل منها upsharge العنوان مختلف، وبالعكس.لكن قل مثلا stone_id = 412 و upcharge_title = "الياقوت" يجب أن يحدث هذا المزيج مرة واحدة فقط.

لابأس:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "ruby"

هذا ليس على ما يرام:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "sapphire"

هل هناك استعلام سيجد التكرارات في كلا الحقلين؟وإذا كان ذلك ممكنًا، فهل هناك طريقة لتعيين قاعدة البيانات الخاصة بي بحيث لا تسمح بذلك؟

أنا أستخدم إصدار MySQL 4.1.22

هل كانت مفيدة؟

المحلول

ويجب إعداد مفتاح مركب بين الحقلين. وهذا يتطلب stone_id فريدة من نوعها وupcharge_title لكل صف.

وبقدر العثور على تكرارات محاولة هذا:

select   stone_id,
         upcharge_title,
         count(*)
from     your_table
group by stone_id,
         upcharge_title
having   count(*) > 1

نصائح أخرى

لقد وجدت أنه من المفيد إضافة فهرس غير عادي باستخدام "ALTER IGNORE" الذي يزيل التكرارات ويفرض سجلات فريدة يبدو أنك ترغب في القيام بها.لذلك سيكون بناء الجملة:

ALTER IGNORE TABLE `table` ADD UNIQUE INDEX(`id`, `another_id`, `one_more_id`);

يؤدي هذا إلى إضافة القيد الفريد بشكل فعال مما يعني أنه لن يكون لديك سجلات مكررة أبدًا ويقوم التجاهل بحذف التكرارات الموجودة.

يمكنك قراءة المزيد عن إيه ALTER IGNORE هنا: http://mediakey.dk/~cc/mysql-remove-duplicate-entries/

تحديث:لقد أبلغتنيInquisitive أن هذا قد يفشل في إصدارات MySql> 5.5:

يفشل في MySQL> 5.5 وعلى جدول Innodb ، وفي Percona بسبب ميزة إنشاء فهرس INNODB السريع [http://bugs.mysql.com/bug.php?id=40344].في هذه الحالة الجولة الأولى set session old_alter_table=1 ثم الأمر أعلاه سوف تعمل بشكل جيد

تحديث - ALTER IGNORE تمت الإزالة في 5.7

من مستندات

اعتبارًا من MySQL 5.6.17 ، يتم إهمال جملة التجاهل واستخدامه يولد تحذيرًا.تمت إزالة التجاهل في MySQL 5.7.

أحد عروض مطوري MySQL بديلين:

  • قم بالتجميع حسب الحقول الفريدة وحذفها كما هو موضح أعلاه
  • أنشئ جدولًا جديدًا وأضف فهرسًا فريدًا واستخدمه INSERT IGNORE, ، السابق:
CREATE TABLE duplicate_row_table LIKE regular_row_table;
ALTER TABLE duplicate_row_table ADD UNIQUE INDEX (id, another_id);
INSERT IGNORE INTO duplicate_row_table SELECT * FROM regular_row_table;
DROP TABLE regular_row_table;
RENAME TABLE duplicate_row_table TO regular_row_table;

ولكن اعتمادًا على حجم طاولتك، قد لا يكون هذا عمليًا

ويمكنك العثور على نسخ من هذا القبيل ..

Select
    stone_id, upcharge_title, count(*)
from 
    particulartable
group by 
    stone_id, upcharge_title
having 
    count(*) > 1

لتجد التكرارات:

select stone_id, upcharge_title from tablename group by stone_id, upcharge_title having count(*)>1

لتقييد تجنب هذا في المستقبل، إنشاء مفتاح فريد مركب على هذين المجالين.

وبالمناسبة، قيد فريد مركب على الطاولة من شأنه أن يمنع هذا من الحدوث في المقام الأول.

ALTER TABLE table
    ADD UNIQUE(stone_id, charge_title)

(وهذا صحيح T-SQL. غير متأكدة من الخلية).

وهذا المنصب SO ساعدتني، ولكن أردت أيضا أن نعرف كيفية حذف والحفاظ على واحد من الصفوف ... وهنا حل PHP لحذف الصفوف المكررة والحفاظ على واحد (في حالتي لم يكن هناك سوى 2 الأعمدة و هو في وظيفة لتطهير الجمعيات الفئة مكررة)

$dupes = $db->query('select *, count(*) as NUM_DUPES from PRODUCT_CATEGORY_PRODUCT group by fkPRODUCT_CATEGORY_ID, fkPRODUCT_ID having count(*) > 1');
if (!is_array($dupes))
    return true;
foreach ($dupes as $dupe) {
    $db->query('delete from PRODUCT_CATEGORY_PRODUCT where fkPRODUCT_ID = ' . $dupe['fkPRODUCT_ID'] . ' and fkPRODUCT_CATEGORY_ID = ' . $dupe['fkPRODUCT_CATEGORY_ID'] . ' limit ' . ($dupe['NUM_DUPES'] - 1);
}

وعلى (الحد NUM_DUPES - 1) هو ما يحافظ على صف واحد ...

وشكر جميع

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top