كيف يمكنني عمل بيان SQL الذي يجد سجلات غير مرتبطة؟
-
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
) أداء أفضل بكثير.
لذلك دائمًا ، يستحق التحقق من كلا الإصدارين.
حدد ... حيث معرف ليس في (حدد ...)