كيف يمكنني عمل بيان SQL الذي يجد سجلات غير مرتبطة؟

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

  •  21-09-2019
  •  | 
  •  

سؤال

لدي جدولين على النحو التالي:

tblCountry (countryID, countryCode)

tblProjectCountry(ProjectID, countryID)

ال tblCountry الجدول هو قائمة بجميع البلدان مع رموزها و tblProjectCountry يربط الجدول بعض البلدان بمشاريع معينة. أحتاج إلى بيان SQL الذي يعطيني قائمة بالبلدان برمز بلدها ليس له سجل مرتبط في tblProjectCountry الطاولة. وصلت حتى الآن إلى هنا:

SELECT     tblCountry.countryID, tblCountry.countryCode
FROM         tblProjectCountry INNER JOIN
                      tblCountry ON tblProjectCountry.countryID = tblCountry.countryID
WHERE     (SELECT     COUNT(ProjectID)
                         FROM         tblProjectCountry 
                         WHERE     (ProjectID = 1) AND (countryID = tblCountry.countryID)) = 0

البيان أعلاه يخلع صحيحًا ولكنه لا يعطي النتيجة الدقيقة التي أبحث عنها. هل أستطيع مساعدتك؟

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

المحلول

هل هذا فعال؟

SELECT countryID, countryCode 
  FROM tblCountry 
  WHERE countryID NOT IN ( SELECT countryID FROM tblProjectCountry )

نصائح أخرى

بديل آخر:

SELECT outerTbl.countryID, outerTbl.countryCode 
    FROM tblCountry AS outerTbl
    WHERE NOT EXISTS 
        (
            SELECT countryID FROM tblProjectCountry WHERE countryID = outerTbl.countryID
        )

هذا يستخدم ما يسمى أ مسمة فرعية مرتبطة

لاحظ أنني أستفيد أيضًا من الكلمة الرئيسية الموجودة (أنظر أيضا)

على SQL Server ، لا يوجد بشكل عام يعتقد أنه أكثر أداء. على RDMS الأخرى قد تختلف الأميال الخاصة بك.

هناك ، على الأقل ، طريقتان للعثور على سجلات غير مرتبطة.

1. باستخدام LEFT JOIN

SELECT DISTINCT -- each country only once
  tblCountry.countryID,
  tblCountry.tblCountry 
FROM
  tblCountry 
  LEFT JOIN
    tblProjectCountry
  ON
    tblProjectCountry.countryID = tblCountry.countryID
WHERE
  tblProjectCountry.ProjectID IS NULL -- get only records with no pair in projects table
ORDER BY
  tblCountry.countryID

مثل إريكالين ذكر هذا يمكن أداء ليس جيدا.

2. باستخدام NOT EXISTS

نسخة مختلفة من استخدام NOT EXISTS أو IN اقترح من قبل Rohancragg و اخرين:

SELECT
  tblCountry.countryID,
  tblCountry.tblCountry 
FROM
  tblCountry 
WHERE
  -- get only records with no pair in projects table
  NOT EXISTS (SELECT TOP 1 1 FROM tblProjectCountry WHERE tblProjectCountry.countryID = tblCountry.countryID) 
ORDER BY
  tblCountry.countryID

يعتمد على DBMS وحجم البلدان وجداول المشاريع يمكن أن يكون كل من الإصدار أفضل.

في اختباري على MS SQL 2005 لم يكن هناك فرق كبير بين الاستعلام الأول والثاني للجدول مع ~ 250 دولة و ~ 5000 المشاريع. ولكن على الطاولة مع أكثر من 3 أمتار المشاريع الإصدار الثاني (باستخدام NOT EXISTS) أداء أفضل بكثير.

لذلك دائمًا ، يستحق التحقق من كلا الإصدارين.

حدد ... حيث معرف ليس في (حدد ...)

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