اگر NOT IN در SQL ناگهان هیچ ردیفی برنمیگرداند، وجودِ NULL در مجموعهٔ سمتِ راست را بررسی کنید. «عضو نبودن» با «هنوز معلوم نبودنِ عضویت» یک نتیجه ندارد. این صفحه روی سه ردیفِ ساختهشده، مقدارِ منطقیِ شرط، شناسههای عبورکرده از WHERE و شمارشِ دادههای موجود را واقعاً با SQLite اجرا میکند؛ خانهٔ نامعلوم را با صفر پُر نمیکند.
جدولِ کوچک و قابلحساب
جدولِ item سه ردیف دارد: شناسهٔ۱با x=۰،شناسهٔ۲با x=۲وشناسهٔ۳با x=NULL. جدولِ rhs دو مقدارِ۲وNULLدارد. همهٔ این دادهها آموزشیاند؛ صفرِ ردیفِ اول مقدارِ واقعیِ همین مثال است، نه جایگزینِ خانهٔ خالیِ سوم. کلِ پایگاه در حافظه ساخته و در پایان بسته میشود.
در گزارشِ JSON، NULL به صورتِ null دیده میشود؛ این نمایشِ انتقالیِ Python است و معنایِ منطقیِ SQL را خودکار به قراردادِ API تبدیل نمیکند. برای خواندنِ جدول، ستونِ مقدارِ predicate را از فهرستِ شناسههایی که WHERE پذیرفته جدا ببینید. WHERE فقط نتیجهٔ درست را عبور میدهد؛ غلط وNULLهر دو ردیف را کنار میگذارند.
مقایسه با NULL همان آزمونِ نبودن نیست
شرطِ x=NULLهیچیک از سه شناسه را عبور نمیدهد؛ برای خانهٔ تهی هم نتیجهٔ مقایسه، درست نیست. شرطِ x IS NULLدر همین داده فقط شناسهٔ۳را میدهد. این دو عبارت برای یک هدف نوشته نشدهاند. اگر قصدتان یافتنِ مقدارِ موجودِ صفر است، از شرطِ مناسبِ همان مقدار استفاده کنید؛ صفر را تهی فرض نکنید.
در جدولِ حقیقتِ تمرین، برای ردیفِ۱عضویت در مجموعهٔ۲وNULLنامعلوم میشود:۰با۲برابر نیست، اما جزءِ نامعلومِ سمتِ راست امکانِ نتیجهٔ قطعیِ «عضو نیست» را نمیدهد. نقیضِ این نامعلومی هم درست نمیشود. ردیفِ۲عضویتِ درست دارد و NOT INآن غلط است؛ ردیفِ۳نیز در مجموعهٔ غیرخالی نتیجهٔ نامعلوم دارد.
سه مجموعهٔ سمتِ راست، سه خروجی
| شرطِ اجراشده | شناسههای عبوری | نکته |
|---|---|---|
| NOT IN با۲وNULL | هیچ | ردیفِ نامساوی هم نامعلوم است |
| NOT IN پس از حذفِ NULLازrhs | ۱ | NULLِ سمتِ چپ هنوز عبور نمیکند |
| NOT IN با زیرپرسوجوی خالی | ۱،۲،۳ | در SQLite حتی NULLِ چپ هم عضوِ مجموعهٔ خالی نیست |
حالتِ خالی مهم است؛ نباید یک جملهٔ کلیِ «هرجا NULLباشد NOT INهمیشه NULLاست» بنویسیم. این تمرین با زیرپرسوجوی WHERE 0 مجموعهٔ خالی میسازد. قواعدِ syntaxِ فهرستِ خالی در موتورهای دیگر ممکن است فرق کنند؛ نتیجه و قرارداد را برای موتورِ خودتان بررسی کنید.
NOT EXISTS را بیقید جایگزین نکنیم
در پرسوجوی NOT EXISTSبا شرطِ برابریِ b.x=a.x،شناسههای۱و۳برمیگردند. برای NULLِ چپ هیچ تطبیقِ برابریِ درست پیدا نشده است؛ پس نبودِ ردیفِ مطابق، درست میشود. این رفتار با NOT INِ مجموعهٔ غیرخالی یکسان نیست. اگر سیاستِ شما حذفِ NULLِ چپ است، آن تصمیم باید جدا نوشته شود.
نسخهٔ دومِ تمرین، a.x IS NOT NULLرا هم اضافه میکند و فقط شناسهٔ۱میماند. هر دو خروجی واقعاً assert شدهاند. انتخابِ یکی از آنها وابسته به معنایِ داده و هدفِ گزارش است؛ حذفِ خاموشِ ردیفِ بیمقدار میتواند پوششِ گزارش را عوض کند. هیچکدام از دو دستور علتِ نبودِ مقدار را کشف نمیکند.
COUNTِ کدام چیز را میخواهیم؟
روی همان جدول، COUNT(*)برابر۳وCOUNT(x)برابر۲است؛ دومی فقط مقدارهای غیرِNULLرا میشمارد و صفر را هم موجود میداند. SUM(x)برابر۲میشود. اگر فقط جمع را نشان دهیم، معلوم نیست یک مقدار در دسترس نبوده است؛ تعدادِ ردیف و تعدادِ مقدارِ حاضر را کنارِ معیار نگه دارید.
شکافِ داده در گزارشِ تماس دربارهٔ معنایِ نبود و پوشش است؛ اینجا خطایِ predicate و شمارشِ واقعیِ SQL را اجرا کردیم. سیاستِ دادهٔ گمشده هم جایگزینیِ آماری در مدلسازی را بررسی میکند؛ این پرسوجو هیچ imputation انجام نمیدهد.
پیش از اتصالِ گزارش به تصمیم
فایلِ Python کتابخانهٔ استاندارد میخواهد و نسخهٔ SQLiteِ اجرا را در نتیجه ثبت میکند. پایگاهِ عملیاتی یا CRMخوانده و تغییر داده نمیشود. برای استفادهٔ واقعی، نامِ ستون و قراردادِ تهی را از مسئولِ داده بگیرید و نتیجهٔ پرسوجو را با چند شناسهٔ مجاز تطبیق دهید؛ پیامِ موفقِ اجرای query صحتِ معنایِ گزارش نیست.
اگر گزارشِ تحلیلِ تماس در اپرابین را بررسی میکنید، واحدِ شمارش و پوششِ شاهد را در درخواستِ بررسی مطرح کنید. این نمونه ساختارِ داخلیِ پایگاه یا استفاده از SQLiteدر اپرا را اعلام نمیکند؛ فقط نمونهٔ مستقلی برای پیداکردنِ یک خطای مشخصِ محاسباتی است.
فایل تمرین و منبع
کدِ کاملِ محلی و کنترلهای اصیلِ تمرین · دادهٔ ساختگی و خروجیِ اجرای واقعی
- SQLite،بخشهایIN/NOT IN،EXISTSوWHERE/منطقِ عبارت؛ فقط بخشهای مرتبط خوانده شدند، صفحه با بهروزرسانی۱۴اوت۲۰۲۶
- SQLite،تعریفِ COUNTوSUMوNULL؛ بخشِ مرتبط، صفحه با بهروزرسانی۱۳نوامبر۲۰۲۵
منابع در 2026-11-04 خوانده شدند؛ این تاریخ، تاریخ انتشار منبع نیست. مثالها و فایلهای این راهنما آموزشی و ساختهٔ تحریریهاند.