Kifungu cha NOT IN cha MySQL Kimeelezwa: Sarufi, Vizingiti vya NULL, Utendaji & Mazoea Mazuri

1. Ni Nini Clause ya NOT IN ya MySQL? — Kufanya Uondoa Data Kuwa na Ufanisi Zaidi

Wakati unafanya kazi na hifadhidata katika MySQL, kuna hali nyingi za kushangaza ambapo unahitaji kurejesha data huku “ukiondoa” thamani au masharti maalum. Kwa mfano, unaweza kutaka kuonyesha orodha ya watumiaji isipokuwa wale ambao wamejisajili kutoka, au kujumlisha data ukiweka nje vitambulisho vinavyoonekana kwenye orodha nyeusi. Hali hizi hutokea mara kwa mara katika mazingira ya biashara na maendeleo. Hapa ndipo clause ya NOT IN inavyokuwa na manufaa makubwa.

Clause ya NOT IN ni hali yenye nguvu ya SQL inayokuwezesha kutoa data ambayo hailingani na thamani zilizobainishwa au matokeo ya subquery. Mbali na uondoa rahisi kwa kutumia orodha, kuichanganya na subqueries za kisasa kunaruhusu mifumo mbalimbali ya uondoa.

Hata hivyo, kulingana na jinsi inavyotumika, NOT IN ina vizingiti na hatari zinazowezekana. Hasa, tabia yake wakati thamani za NULL zinahusishwa, masuala ya utendaji katika hifadhidata kubwa, na tofauti ikilinganishwa na NOT EXISTS ni mambo muhimu ya kuelewa kwa kiwango cha vitendo.

Katika makala hii, tunaelezea kwa kina clause ya MySQL NOT IN—kutoka kwenye misingi hadi matumizi ya juu—pamoja na tahadhari na kulinganisha na mbinu mbadala za uondoa, tukitumia mifano halisi. Iwe wewe ni mgeni wa SQL au tayari unaitumia mara kwa mara, mwongozo huu unatoa maarifa ya thamani. Hakikisha unasoma hadi mwisho na kutumia maarifa haya kuboresha ujuzi wako wa SQL na kuongeza ufanisi wa mtiririko wako wa kazi.

2. Sarufi ya Msingi na Mifano ya Matumizi ya NOT IN

Clause ya NOT IN katika MySQL inatumika unapohitaji kurejesha rekodi ambazo hazilingani na thamani yoyote ya thamani zilizobainishwa. Sarufi yenyewe ni rahisi, lakini katika hali za dunia halisi, inaonyesha manufaa katika hali nyingi. Hapa, tunatoa sarufi ya msingi na mifano ya vitendo.

[Basic Syntax]

SELECT column_name FROM table_name WHERE column_name NOT IN (value1, value2, ...);

Uondoa kwa Orodha Rahisi

Kwa mfano, ikiwa unataka kurejesha watumiaji ambao majina yao si “Yamada” au “Sato”, utaandika tamko la SQL lifuatalo:

SELECT * FROM users WHERE name NOT IN ('Yamada', 'Sato');

Kutekeleza swali hili kunarejesha rekodi zote za watumiaji isipokuwa wale walio na majina “Yamada” na “Sato”. Kwa kuwa orodha ya uondoa inahitaji tu thamani zilizotenganishwa kwa koma, ni rahisi kuandika na kuelewa.

Uondoa wa Kijumla kwa Kutumia Subquery

Clause ya NOT IN pia inaweza kutumia subquery ndani ya mabano, si orodha iliyowekwa tu. Hii ni muhimu hasa unapohitaji kuondoa vitambulisho vya watumiaji vinavyokidhi masharti maalum.

SELECT * FROM users
WHERE id NOT IN (SELECT user_id FROM blacklist WHERE is_active = 1);

Katika mfano huu, vitambulisho vya watumiaji vilivyo alama kuwa hai katika jedwali blacklist (is_active = 1) vinatolewa, na watumiaji waliobaki wanarejeshwa kutoka kwenye jedwali users. Kwa kuchanganya NOT IN na subqueries, unaweza kubadilika kwa urahisi kulingana na mahitaji mbalimbali ya mantiki ya biashara.

Kutumia Masharti Mengi

Ikiwa unahitaji kubainisha masharti ya uondoa kwenye safu nyingi kwa wakati mmoja, NOT IN imeundwa hasa kwa matumizi ya safu moja. Hata hivyo, kwa kuichanganya na subqueries au viunganishi (JOIN), unaweza kushughulikia masharti tata zaidi. Tutayoelezea kwa kina katika sehemu ya mbinu za juu baadaye.

Kama unavyoona, clause ya NOT IN ni muhimu sana unapohitaji kurejesha rekodi zote isipokuwa zile zilizojumuishwa katika orodha iliyobainishwa au matokeo ya subquery. Anza kwa kuonyesha data unayotaka kutoa, na fanya mazoezi ya kutumia orodha rahisi za uondoa na subqueries kwa ufanisi.

3. Vidokezo Muhimu Wakati Thamani za NULL Zipo

Wakati unapotumia clause ya NOT IN, suala moja linalopitwa polepole ni tabia yake wakati thamani za NULL zinahusishwa. Hii ni “shimo” la jadi ambalo linaweza kusababisha makosa sio tu kwa wanaoanza bali hata kwa watumiaji wa SQL wenye uzoefu.

The reason is that the evaluation logic of NOT IN differs from normal comparisons—it behaves differently when NULL values are included.

Tabia Wakati NULL Imejumuishwa

Suppose we have the following tables:

-- users table
id | name
---+------
 1 | Sato
 2 | Yamada
 3 | Suzuki
 4 | Tanaka

-- blacklist table
user_id
--------
1
NULL

Now consider executing the following SQL statement:

SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM blacklist);

At first glance, it may seem that all users except user_id = 1 (that is, id = 2, 3, 4) would be returned. However, in reality, no rows are returned.

Kwa Nini Hakuna Safu Zilizorejeshwa?

The reason lies in SQL’s three-valued logic (TRUE / FALSE / UNKNOWN).
When NULL is included in the NOT IN list, the comparison result becomes UNKNOWN, and MySQL does not include those rows in the result set.

In other words, since it cannot definitively determine that a value does not match any item in the list, the overall condition evaluates to false.

Mambo ya Mara kwa Mara Yanayosababisha Tatizo

This issue frequently occurs when using subqueries. If NULL values exist in a blacklist or unsubscribe list, data may not be retrieved as expected.

Problems such as “no data is returned” or “records are not properly excluded” often trace back to hidden NULL values.

Hatua za Kuzuia na Suluhisho

To prevent issues caused by NULL values, you must exclude NULL from the NOT IN list. Specifically, add an IS NOT NULL condition inside the subquery.

SELECT * FROM users
WHERE id NOT IN (
  SELECT user_id FROM blacklist WHERE user_id IS NOT NULL
);

With this adjustment, even if the blacklist table contains NULL values, the query will correctly retrieve users who are not on the blacklist.

Mambo Muhimu

  • If NULL exists in a NOT IN list, the query may return zero rows
  • Always combine subqueries with IS NOT NULL when using NOT IN
  • If data is unexpectedly missing, check for hidden NULL values first

4. NOT IN vs NOT EXISTS — Kulinganisha Mbadala

When specifying exclusion conditions in MySQL, NOT EXISTS is another common alternative to NOT IN. While both can achieve similar results, they differ in behavior, NULL handling, and performance characteristics. In this section, we compare NOT IN and NOT EXISTS, and explain their respective advantages and disadvantages.

Ulinganisho wa Sarufi ya Msingi

[Exclusion Using NOT IN]

SELECT * FROM users
WHERE id NOT IN (SELECT user_id FROM blacklist WHERE user_id IS NOT NULL);

[Exclusion Using NOT EXISTS]

SELECT * FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM blacklist b WHERE b.user_id = u.id
);

Both queries retrieve users who are not registered in the blacklist.

Kushughulikia Thamani za NULL

NOT IN

  • Ikiwa NULL imejumuishwa katika orodha au matokeo ya subquery, swali linaweza kutofanya kama ilivyotarajiwa (lanaweza kurudisha safu sifuri)
  • Inahitaji sharti la wazi IS NOT NULL kama kinga

NOT EXISTS

  • Inafanya kazi kwa usahihi hata kama matokeo ya subquery yana NULL
  • Kwa ujumla ni salama zaidi kwa sababu haijathiriwi na thamani za NULL

Tofauti za Utendaji

The optimal approach depends on data volume and table structure, but generally:

  • For small datasets or fixed lists, NOT IN performs adequately
  • For large subqueries or complex conditions, NOT EXISTS or LEFT JOIN often provides better performance

As the number of blacklist records increases, NOT EXISTS frequently becomes more efficient. Depending on the MySQL version and indexing, NOT EXISTS can be very fast when proper indexes are available, since it performs an existence check for each row.

Miongozo ya Kuchagua

  • Ikiwa thamani za NULL zinaweza kuwepo → Tumia NOT EXISTS
  • Ikiwa unazuia orodha isiyobadilika au thamani rahisiNOT IN inatosha
  • Ikiwa utendaji ni muhimu → Angalia mpango wa utekelezaji kwa EXPLAIN na uchague ipasavyo (fikiria JOIN au NOT EXISTS )

Mifano ya Kesi

Mfano wa Tatizo Kutumia NOT IN

-- If blacklist.user_id contains NULL
SELECT * FROM users
WHERE id NOT IN (SELECT user_id FROM blacklist);
-- → May return zero rows

Mfano Salama wa Kuondoa Kutumia NOT EXISTS

SELECT * FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM blacklist b WHERE b.user_id = u.id
);
-- → Correct results regardless of NULL values

Muhtasari

  • NOT IN ni rahisi lakini ni dhaifu kwa thamani za NULL
  • NOT EXISTS ni imara dhidi ya NULL na hutumika sana katika mazingira ya uzalishaji
  • Chagua kulingana na sifa za data na utendaji unaohitajika

5. Mambo ya Utendaji

Unapofanya kazi na seti kubwa za data katika SQL, utendaji wa maswali ni muhimu sana. Kulingana na hali na kiasi cha data, kutumia NOT IN au NOT EXISTS kunaweza kusababisha tofauti kubwa katika kasi ya utekelezaji. Katika sehemu hii, tunazingatia athari za utendaji wa kifungu cha NOT IN, pamoja na vidokezo vya uboreshaji na mambo muhimu ya kuzingatia.

Sifa za Utendaji za NOT IN

Kifungu cha NOT IN kinachukua rekodi ambazo hazilingani na thamani zozote katika orodha iliyobainishwa au matokeo ya subquery. Kinafanya kazi kwa ufanisi na orodha ndogo au majedwali, lakini kinaweza kupungua kasi katika hali zifuatazo:

  • Wakati subquery inarudisha idadi kubwa ya safu
  • Wakati safu iliyotengwa haijapangwa na faharasa
  • Wakati thamani za NULL zipo katika matokeo ya subquery

Haswa, ikiwa subquery ina maelfu kumi au mamia ya maelfu ya safu na hakuna faharasa iliyofafanuliwa, MySQL inaweza kufanya kulinganisha kamili, na kusababisha kupungua kwa kasi kwa kiasi kikubwa.

Umuhimu wa Kuweka Faharasa

Kuongeza faharasa kwenye safu inayotumika kwa kuondoa (kwa mfano, user_id) humruhusu MySQL kufanya kulinganisha na kuchuja kwa ufanisi zaidi. Safu zinazotumika katika subqueries au joins zinapaswa kuwekwa faharasa inapofaa.

CREATE INDEX idx_blacklist_user_id ON blacklist(user_id);

Kwa kuongeza faharasa kama hii, utendaji wa maswali ya NOT IN na NOT EXISTS unaweza kuboreshwa kwa kiasi kikubwa.

Ulinganisho wa Utendaji: NOT IN vs NOT EXISTS

  • Orodha ndogo, zilizowekwa: NOT IN kwa kawaida ni haraka
  • Subqueries kubwa: NOT EXISTS au LEFT JOIN mara nyingi ni bora zaidi

Kwa sababu mpango wa utekelezaji wa MySQL (matokeo ya EXPLAIN) hubadilika kulingana na toleo na muundo wa jedwali, ubao wa utendaji unapaswa kila wakati kujumuisha majaribio halisi.

Kuangalia Mpango wa Utekelezaji kwa EXPLAIN

Ili kubaini ni swali lipi linafanya vizuri zaidi, tumia amri ya MySQL EXPLAIN:

EXPLAIN SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM blacklist WHERE user_id IS NOT NULL);

Hii inakuwezesha kuona ni faharasa zipi zinatumika na ikiwa majedwali yoyote yanachunguzwa kikamilifu—maelezo ambayo yanaathiri moja kwa moja utendaji.

Mikakati ya Uboreshaji kwa Seti Kubwa za Data

  • Hifadhi matokeo ya kati katika jedwali la muda ili kupunguza mzigo wa subquery
  • Tumia usindikaji wa batch au caching ikiwa utendaji bado haujatosha
  • Andika upya kwa kutumia LEFT JOIN ... IS NULL (katika baadhi ya hali hii inaboresha kasi)

Mambo Muhimu

  • NOT IN inaweza kuwa polepole wakati subqueries ni kubwa au faharasa hazipo
  • Ubunifu sahihi wa faharasa na mapitio ya maswali yanaweza kuboresha utendaji kwa kiasi kikubwa
  • Fikiria NOT EXISTS au LEFT JOIN, na kila wakati thibitisha matokeo kwa kutumia EXPLAIN

Katika mazingira ya uzalishaji, kila wakati chagua swali linalofaa zaidi kulingana na ukubwa wa data na mara ya matumizi.

6. Matumizi ya Kawaida na Mbinu za Juu

Kifungu cha NOT IN hakijazuiliwa kwa kuondoa rahisi. Kwa mbinu za juu, unaweza kufanya uchambukizo wa data unaobadilika zaidi. Hapa tunatambua mifumo inayotumika sana na mbinu za vitendo.

Kuondoa Safu Nyingi (Uondoa wa Ufunguo wa Mchanganyiko)

Ingawa NOT IN hutumika kwa safu moja, kuna hali ambapo unahitaji kuondoa mchanganyiko wa safu nyingi. Katika hali hizo, NOT EXISTS au LEFT JOIN ni bora zaidi.

[Mfano: Kuondoa mchanganyiko maalum wa customer_id na product_id kutoka kwenye jedwali la orders]

SELECT * FROM orders o
WHERE NOT EXISTS (
  SELECT 1 FROM blacklist b
  WHERE b.customer_id = o.customer_id
    AND b.product_id = o.product_id
);

Hii inaondoa mchanganyiko wote wa “customer_id × product_id” uliosajiliwa kwenye orodha nyeusi.

Kuondoa mechi ya sehemu (Kutumia NOT LIKE)

Kwa kuwa NOT IN inafanya kazi tu na mechi kamili, tumia NOT LIKE unapoondoa mifumo maalum ya herufi. Kwa mfano, kuondoa watumiaji ambao anwani za barua pepe zinaanza na “test@”:

SELECT * FROM users WHERE email NOT LIKE 'test@%';

Ili kuondoa mifumo mingi kwa wakati mmoja, changanya masharti kwa kutumia AND:

SELECT * FROM users
WHERE email NOT LIKE 'test@%'
  AND email NOT LIKE 'sample@%';

Kushughulikia Orodha Kubwa za Kuondoa

Kuweka mamia au maelfu ya thamani moja kwa moja ndani ya NOT IN hupunguza usomaji na inaweza kuathiri utendaji.

Katika hali kama hizi, tumia jedwali maalum au subquery kudhibiti orodha ya kuondoa kwa usafi zaidi:

-- Example: Store exclusion list in blacklist table
SELECT * FROM users
WHERE id NOT IN (SELECT user_id FROM blacklist WHERE user_id IS NOT NULL);

Kuunganisha na Fonctions za Jumla

Unaweza pia kutumia NOT IN na subqueries ambazo zina masharti ya jumla.

[Mfano: Pata wateja ambao hawajafanya maagizo mwezi huu]

SELECT * FROM customers
WHERE id NOT IN (
  SELECT customer_id FROM orders
  WHERE order_date >= '2025-06-01'
    AND order_date < '2025-07-01'
);

Kutumia JOIN Badala ya Subquery

Katika baadhi ya hali, unaweza kupata matokeo sawa kwa kutumia LEFT JOIN pamoja na IS NULL.

Chagua njia inayofaa zaidi kulingana na utendaji na usomaji.

SELECT u.*
FROM users u
LEFT JOIN blacklist b ON u.id = b.user_id
WHERE b.user_id IS NULL;

Njia hii ni muhimu hasa wakati utendaji wa subquery haujulikani au viashiria (indexes) vinafanya kazi vizuri.

Mambo Muhimu

  • Tumia NOT EXISTS au JOIN kwa kuondoa nguzo nyingi
  • Changanya na NOT LIKE kwa kuondoa sehemu za herufi
  • Dhibiti orodha kubwa za kuondoa kwa kutumia majedwali au subqueries
  • JOIN + IS NULL inaweza pia kuboresha utendaji

7. Maswali Yanayoulizwa Mara kwa Mara (FAQ)

Hapa kuna baadhi ya maswali yanayoulizwa mara kwa mara na pointi za kawaida zinazojitokeza kuhusu kifungu cha MySQL NOT IN. Majibu yanazingatia masuala ya vitendo ambayo mara nyingi hutafutwa katika hali halisi.

Q1. Ni tofauti gani kati ya NOT IN na IN?

A.
IN hurejesha data inayolingana na thamani yoyote kwenye orodha iliyobainishwa, wakati NOT IN hurejesha data ambayo hailingani na thamani yoyote kwenye orodha. Sintaksia yao ni karibu sawa, lakini ikiwa unataka kuondoa thamani fulani, unapaswa kutumia NOT IN.

Q2. Nini kinatokea ikiwa thamani za NULL zipo wakati wa kutumia NOT IN?

A.
Kama thamani za NULL zimejumuishwa kwenye orodha au subquery, NOT IN inaweza kurudisha safu sifuri au kutoa matokeo yasiyotabiriwa. Ni salama zaidi kuondoa NULL waziwazi kwa kutumia IS NOT NULL.

Q3. Nitachagua vipi kati ya NOT IN na NOT EXISTS?

A.

  • Kama thamani za NULL zinawezekana au subquery inahusishwa, NOT EXISTS ni ya kuaminika zaidi.
  • Kwa orodha zisizobadilika au kuondoa rahisi, NOT IN inafanya kazi vizuri.
  • Kwa kuwa utendaji unaweza kutofautiana kulingana na mipango ya utekelezaji na wingi wa data, chagua kulingana na hali yako maalum.

Q4. Wakati mwingine maswali yanayotumia NOT IN huwa polepole. Ninawezaje?

A.

  • Ongeza kiashiria (index) kwenye safu lililotumika katika sharti la kuondoa
  • Punguza ukubwa wa matokeo ya subquery au panga data katika jedwali la muda
  • Fikiria kuandika upya swali kwa kutumia NOT EXISTS au LEFT JOIN ... IS NULL
  • Tumia EXPLAIN kuchambua mpango wa utekelezaji na kutambua vikwazo

Q5. Ninawezaje kuondoa kulingana na safu nyingi?

A.
Kwa kuwa NOT IN imetengenezwa kwa matumizi ya safu moja, tumia NOT EXISTS au LEFT JOIN unapohitaji kutenga mchanganyiko katika safu nyingi. Changanya hali za safu nyingi ndani ya subquery.

Q6. Ninapaswa kuwa mwangalifu nini wakati subquery inarudisha safu nyingi?

A.
Wakati subquery inarudisha idadi kubwa ya safu, NOT IN inaweza kukabiliwa na kupungua kwa utendaji. Tumia indexing, majedwali ya muda, au urekebishe query ili kuweka subquery ndogo iwezekanavyo.

Q7. Kama siezi kupata matokeo yanayotarajiwa, ninapaswa kuangalia nini?

A.

  • Thibitisha kuwa hakuna maadili ya NULL yaliyojumuishwa bila kukusudia
  • Endesha subquery peke yake ili kuthibitisha matokeo yake
  • Angalia makosa katika hali za WHERE au mantiki ya JOIN
  • Pitia tabia maalum ya toleo la MySQL na hati rasmi ikiwa ni lazima

8. Hitimisho

Kifungu cha NOT IN cha MySQL ni muundo muhimu sana kwa kurejesha data kwa ufanisi ambayo haikidhi hali maalum. Kutoka orodha za kutenga rahisi hadi uchujaji unaobadilika na subqueries, inaweza kutumika katika hali nyingi za vitendo.

Hata hivyo, kuna mazingatio muhimu katika matumizi ya ulimwengu halisi, kama vile kushughulikia maadili ya NULL na kupungua kwa utendaji katika seti kubwa za data. Masuala kama masuala ya zero-result queries zisizotarajiwa kutokana na maadili ya NULL au utekelezaji wa polepole unaosababishwa na subqueries kubwa yanahitaji umakini kutoka kwa wanaoanza na watengenezaji wenye uzoefu.

Kwa kuelewa pia mbinu mbadala kama vile NOT EXISTS na LEFT JOIN ... IS NULL, unaweza kuandika masuala salama na yenye ufanisi zaidi ya SQL. Daima chagua njia inayofaa zaidi kulingana na malengo yako na ukubwa wa data.

Mambo Muhimu ya Kuchukua

  • NOT IN ni yenye ufanisi kwa hali za kutenga rahisi
  • Daima lindana dhidi ya maadili ya NULL (fanya IS NOT NULL kuwa tabia)
  • Kama utendaji ni wasiwasi, zingatia mikakati ya indexing au kutumia NOT EXISTS na mbadala za JOIN
  • Daima thibitisha ufanisi kwa kutumia mpango wa utekelezaji (EXPLAIN)

Epuka “makosa” ya SQL na fanya mazoezi ya uchimbaji data wenye busara kwa kutumia dhana zilizoshughulikiwa katika makala hii katika kazi yako ya kila siku na kujifunza.