TGViewer
کانال تخصصی SQLSERVER کانال تخصصی SQLSERVER @sqlserver_professional · 848 subscribers
Post #540 1.74K
#آموزش: خطر استفاده از عملگر Not IN ❗️

در این آموزش علاوه بر آشنایی با نحوه عملکرد عملگر Not IN ، با نکاتی پیرامون مقدار null در sqlserver هم آشنایی پیدا خواهید کرد.

خیلی از مواقع ممکن هست برای تهیه گزارشاتی مانند لیست کارمندانی که حقوق فلان ماه رو دریافت نکرده اند، لیست کالاهایی که رزرو سفارش نشده اند و ... از عملگر Not IN به صورت زیر استفاده کنیم :
select * from first_table as a جدول حاوی کلیه رکوردها
where a.id Not IN(Select id from second_table where ....)

به عنوان یک اشاره مختصر : همونطور که میدونید عملگرهایی مانند Exists - IN - Not IN - Not Exists جهت انجام عملیات از Join (semi join - inner join) استفاده می کنند .
در هر حال، جهت تولید خروجی نهایی، باید یک مقایسه بین id رکوزردهای جدول اول (first table) و جدول دوم (second table) که دارای شرط خاصی هستند انجام بشود. نکته مهم این هست که در عملگر not in این مقایسه به دنباله ای از ANd ها تبدیل می شود ( بر خلاف عملگر IN که به دنباله ای از OR ها تبدیل می شود).
و اما مشکل زمانی ایجاد می شود که در مقایسه ما یک مقدار با null ست شده باشد. به مثال زیر دقت کنید:
SELECT *
FROM dbo.Person
WHERE ID NOT IN (1,2,null)

با بررسی Execution plan خواهید دید که مقایسه به این صورت خواهد بود :
[dbo].[Person].[ID]< > 1) AND
[dbo].[Person].[ID]< >2) AND
[dbo].[Person].[ID]< >null)

به اینصورت خروجی شما همیشه تهی خواهد بود و هیچ رکوردی رو در خروجی نخواهید دید !!!!!
و اما دلیل بروز این مشکل:
دقت کنید برای نمایش یک رکورد، بایستی حاصل مقایسه (عبارت داخل پرانتز) برابر با true شود.
نکته مهم در اینجا وجود مقدار null هست و دو نکته مهم در رابطه با null:

1- نتیجه انجام هر مقایسه یا عملیاتی با null برابر است با null (این مورد رو با نوشتن کوئری های ساده مانند : select null*2 بررسی کنیذ.
2- نتیجه مقایسه منطقی AND هر مقداری با null برابر است با false

با توجه به دو نکته بالا، فرض کنید از جدول اول داریم: id=2
پس در ابتدا حاصل مقایسه ها:
1< >1 —-------------->false
1< >2) —--------------->true
1< > null) —------------->null با توجه به نکته 1
در مرحله دوم انجام AND بین نتایج:
flase AND true AND null —----------------------->false با توجه به نکته 2

راه حل:
1- با استفاده از عملگر Not Exists این مشکل را نخواهید داشت.
2- در صورت ایجاد رابطه (Relationship) بین جداول، جدول Child نمی تواند مقداری که در جدول Parent وجود ندارد را داشته باشد و از آنجایی که فیلذ جدول Parent هم Unique می باشد پس مشکل فوق در استفاده از عملگر Not in پیش نخواهد آمد .

محسن بندامیر @Mohsen_Bandamir
More from @sqlserver_professional
  1. Oct 29, 2022photo post
  2. Sep 13, 2022🗣🗣مژده، مژده: راه اندازی مجدد سایت codeeatsleep.ir با حمایت های خودتان، ما را در جهت انت…
  3. Apr 9, 2021Post #663
  4. Apr 4, 2021Post #662
  5. Mar 30, 2021عملیات انجام شده از زمان بروزرسانی یک رکورد، تا ثبت نهایی تغییرات بر روی دیسک
  6. Mar 30, 2021Post #660
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →