كيف يمكنك أن تجد الصفوف مع الأعمدة متساوية؟

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

  •  08-07-2019
  •  | 
  •  

سؤال

وإذا كان لدي جدول مع 2 الأعمدة الهامة،

CREATE TABLE foo (id INT, a INT, b INT, KEY a, KEY b);

وكيف يمكن أن أجد كافة الصفوف التي تحتوي على حد سواء a وb هي نفسها في كل الصفوف؟ على سبيل المثال، في مجموعة البيانات هذه

id | a | b
----------
1  | 1 | 2
2  | 5 | 42
3  | 1 | 42
4  | 1 | 2 
5  | 1 | 2
6  | 1 | 42

وأريد أن نعود كافة الصفوف باستثناء id=2 لأنها فريدة من نوعها في (a,b). أساسا، أريد أن أجد كافة الصفوف المخالفة التي من شأنها وقف

ALTER TABLE foo ADD UNIQUE (a, b);

وشيء أفضل من ن ^ 2 لحلقة سيكون من الرائع منذ مائدتي لديها صفوف 10M.

بالنسبة نقاط المكافأة : لكيف يمكنني إزالة لكن كل واحد من الصفوف (لا يهمني أي منها، طالما هي واحدة يسار)

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

المحلول

SELECT * 
FROM foo first
JOIN foo second
  ON ( first.a = second.a
       AND first.b = second.b ) 
  AND (first.id <> second.id )

ويجب أن يأتي مع كافة الصفوف حيث الصفوف أكثر من واحد لديه نفس تركيبة من أ و ب.

وآمل فقط أن يكون لديك مؤشر على أعمدة أ و ب.

نصائح أخرى

select * from foo where a = b

وأو أنا في عداد المفقودين شيء؟

===

وتحديث وضوح:

select * from 
foo as a
inner join foo as b
on a.a = b.a AND b.a = b.b
and a.id != b.id

و++++++++++ بعد 3RD الوضوح تحرير:

select f1.id
FROM foo as f1
INNER JOIN foo as f2
ON f1.a = f2.a AND f1.b=f2.b AND f1.id != f2.id

ولكن أنا النار، حتى تحقق ذلك بنفسك.

وجرب هذا:

    With s as (Select a,b from foo group by a,b having Count(1)>1)
Select foo.* from foo,s where foo.a=s.a and foo.b=s.b

وهذا الاستعلام يجب أن تظهر صفوف مكررة في الجدول فو.

هل يمكن أن يرجى توضيح ما عليك القيام به في نهاية المطاف؟ قد يعتمد الحل الأمثل على ذلك (على سبيل المثال، هل تريد ببساطة لحذف كافة الصفوف-dupliucate المفتاح؟)

ويتمثل أحد السبل لمعالجة هذا الجدول (غير متأكد إذا الخلية يدعم ذلك، انها من SYBASE) إذا كان كل ما تريده هو الصفوف الفريدة مرتبطا:

SELECT MIN(id), A, B FROM FOO GROUP BY A, B HAVING COUNT(*)>1

والسؤال المحدد الخاصة بك (على الرغم من أنني قليلا في حيرة لماذا كنت في حاجة إلى كل الصفوف باستثناء معرف = 2) هو:

SELECT F1.*  
FROM FOO F1 , 
     (SELECT A, B FROM FOO GROUP BY A, B HAVING COUNT(*)>1) F2
WHERE F1.A=F2.A and F1.B=F2.B

لحذف كل التكرارات، يمكنك على سبيل المثال قيام

DELETE FOO WHERE NOT EXISTS
(SELECT 1 from
    (SELECT MIN(id) 'min_id' FROM FOO GROUP BY A, B HAVING COUNT(*)>1) UINIQUE_IDS 
 WHERE id = min_id)

وكبديل، يمكنك أن تفعل

  SELECT MIN(id) 'id', A, B INTO TEMPDB..NEW_TABLE 
  FROM FOO GROUP BY A, B HAVING COUNT(*)>1

  TRUNCATE TABLE FOO
  // Drop indices on FOO
  INSERT FOO SELECT * FROM NEW_TABLE
  // Recreate indices on FOO

لا ينبغي أن هذا العمل؟

SELECT * FROM foo WHERE a = b

و=== === تحرير

وماذا عن

SELECT a, b FROM foo GROUP BY a, b HAVING COUNT(*) > 1

و=== النهائي إعادة تحرير قبل أن تتخلى عن هذا السؤال ===

SELECT foo.* FROM foo, (
   SELECT a, b FROM foo GROUP BY a, b HAVING COUNT(*) > 1
) foo2
WHERE foo.a = foo2.a AND foo.b = foo2.b

وهنا نهج آخر

select * from foo f1 where exists(
  select * from foo f2 where
    f1.id != f2.id and
    f1.a = f2.a and
    f1.b = f2.b )

وعلى أي حال، على الرغم من أن أجد شيئا أكثر قابلية للقراءة، إذا كان لديك مثل هذا الجدول ضخمة، يجب عليك مراجعة خطة التنفيذ، الاستعلامات الفرعية لها سمعة سيئة تنطوي على أداء ...

ويجب عليك أن تنظر أيضا إنشاء الفهرس (بدون شرط فريدة من نوعها، من الواضح) لتسريع الاستعلام ... لعمليات ضخمة، وأحيانا يكون من الأفضل لقضاء وقت إنشاء الفهرس، إجراء التحديث ومن ثم إسقاط الفهرس. .. في هذه الحالة، أعتقد فهرس على (أ، ب) من شأنه أن يساعد بالتأكيد الكثير ...

وهدفها المعلن الخاص بك هو لإزالة كل مجموعة مكررة من (a,b). لذلك، يمكنك استخدام طاولة متعددة DELETE:

DELETE t1
  FROM foo t1
  JOIN foo t2 USING (a, b)
 WHERE t2.id > t1.id

وقبل تشغيله، يمكنك التحقق من الصفوف التي ستكون <م> إزالة مع:

SELECT DISTINCT t1.id
  FROM foo t1
  JOIN foo t2 USING (a, b)
 WHERE t2.id > t1.id

ووجملة WHERE يجري t2.id > t1.id أنه سيتم إزالة جميع ولكن واحدة وفقا لأعلى قيمة للid. في الحالة الخاصة بك، فقط الصفوف مع id تساوي 2، ستبقى 5 أو 6.

وإذا كانت قيمة id لا يهم على الإطلاق في المنتج النهائي، وهذا هو، إذا كنت يمكن أن يعاد ترتيب كل منهم، وأنه سيكون على ما يرام، وإذا هو معرف عمود المسلسل، وبعد ذلك فقط "تحديد واضح" على اثنين الأعمدة في جدول جديد، وحذف كافة البيانات من الجدول القديم، ثم قم بنسخ القيم المؤقتة مرة أخرى.

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