كيفية العثور على الصفوف في جدول واحد التي ليس لها الصف المقابل في جدول آخر

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

  •  06-07-2019
  •  | 
  •  

سؤال

ولدي 1: العلاقة بين جدولين 1. أريد أن أجد كافة الصفوف في الجدول ألف التي لم يكن لديك الصف المقابل في جدول B. أنا استخدم هذا الاستعلام:

SELECT id 
  FROM tableA 
 WHERE id NOT IN (SELECT id 
                    FROM tableB) 
ORDER BY id desc

ومعرف هو المفتاح الأساسي في كلا الجدولين. وبصرف النظر عن مؤشرات المفتاح الأساسي، ولدي أيضا مؤشر على tableA (معرف تنازلي).

وعن طريق H2 (جافا قاعدة البيانات جزءا لا يتجزأ)، وهذا يؤدي إلى مسح الجدول الكامل من tableB. أريد أن تجنب تفحص الجدول الكامل.

وكيف يمكنني إعادة كتابة هذا الاستعلام لتشغيل بسرعة؟ ما ينبغي مؤشر I ينبغي؟

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

المحلول

select tableA.id from tableA left outer join tableB on (tableA.id = tableB.id)
where tableB.id is null
order by tableA.id desc 

إذا ديسيبل بك يعرف كيفية القيام تقاطعات مؤشر، وهذا سوف أتطرق فقط مؤشر المفتاح الأساسي

نصائح أخرى

ويمكنك أيضا استخدام exists، منذ بعض الأحيان انها أسرع من left join. كنت قد لقياس لهم معرفة أي واحد التي تريد استخدامها.

select
    id
from
    tableA a
where
    not exists
    (select 1 from tableB b where b.id = a.id)

لإظهار أن exists يمكن أن يكون أكثر كفاءة من left join، وهنا خطط تنفيذ هذه الاستعلامات في SQL Server 2008:

على left join - يمكنك التكلفة الإجمالية الشجرة الفرعية: 1.09724:

على exists - يمكنك التكلفة الإجمالية الشجرة الفرعية: 1.07421:

لديك للتأكد من كل ID في tableA ضد كل ID في tableB. ومن شأن RDBMS متميز تماما (مثل أوراكل) تكون قادرة على تحسين هذا إلى INDEX SCAN سريعة وكاملة وعدم لمس الطاولة على الإطلاق. أنا لا أعرف ما إذا كان محسن H2 هو الذكية مثل ذلك.

وH2 لا تدعم بناء الجملة الطرح لذلك يجب عليك محاولة هذا

select id from tableA
minus
select id from tableB
order by id desc

وهذا قد أداء أسرع؛ هو بالتأكيد يستحق القياس.

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

--Create Sample Data.
d r o p table tableA;
d r o p table tableB;

create table tableA as (
   select rownum-1 ID, chr(rownum-1+70) bb, chr(rownum-1+100) cc 
      from dual connect by rownum<=4
);

create table tableB as (
   select rownum ID, chr(rownum+70) data1, chr(rownum+100) cc from dual
   UNION ALL
   select rownum+2 ID, chr(rownum+70) data1, chr(rownum+100) cc 
      from dual connect by rownum<=3
);

a l t e r table tableA Add Primary Key (ID);
a l t e r table tableB Add Primary Key (ID);

--View Tables.
select * from tableA;
select * from tableB;

--Find all rows in tableA that don't have a corresponding row in tableB.

--Method 1.
SELECT id FROM tableA WHERE id NOT IN (SELECT id FROM tableB) ORDER BY id DESC;

--Method 2.
SELECT tableA.id FROM tableA LEFT JOIN tableB ON (tableA.id = tableB.id)
WHERE tableB.id IS NULL ORDER BY tableA.id DESC;

--Method 3.
SELECT id FROM tableA a WHERE NOT EXISTS (SELECT 1 FROM tableB b WHERE b.id = a.id) 
   ORDER BY id DESC;

--Method 4.
SELECT id FROM tableA
MINUS
SELECT id FROM tableB ORDER BY id DESC;

وأنا لا أستطيع أن أقول لك أي من هذه الطرق ستكون أفضل على H2 (أو حتى لو كان كل منهم سوف تعمل)، لكنني لم أكتب مقالا مفصلا عن الطرق (جيد) المتاحة في TSQL. يمكنك ان تعطي لهم النار ومعرفة ما إذا كان أي منهم يعمل للكم:

http://code.msdn.microsoft كوم / SQLExamples / المعرفة / View.aspx؟ عنوان = QueryBasedUponAbsenceOfData وreferringTitle = الرئيسية

select parentTable.id from parentTable
left outer join childTable on (parentTable.id = childTable.parentTableID) 
where childTable.id is null
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top