Lesson 12 / الدرس 12
SELECT and WHERE / SELECT وWHERE
Asking a table for the rows you want and the columns you need. The syntax takes ten minutes; the part that takes longer is NULL, which does not behave the way your intuition insists it should.
سؤال جدول عن الصفوف التي تريدها والأعمدة التي تحتاجها. والصياغة تأخذ عشر دقائق؛ والذي يأخذ أطول هو NULL، وهو لا يتصرف كما يصر حدسك.
The shape of a query
SELECT name, city which columns
FROM guests which table
WHERE city = 'Cairo' which rows
ORDER BY name in what order
LIMIT 10; how many
written in that order, but the database reads FROM first, then WHERE,
then SELECT — which is why an alias made in SELECT cannot be used in WHERE
NULL — read those slowly, because they are where the surprises live.
NULL — اقرأها ببطء، فهناك تسكن المفاجآت.NULL is not a value
NULL means "no value here", and SQL treats it as unknown rather than as a thing. Every comparison with an unknown produces unknown, not true and not false — and WHERE keeps a row only when its condition is exactly true. So phone <> '0100000001' silently drops the guests who have no phone at all: the database cannot say their number differs, because it does not know their number. And phone = NULL returns nothing ever, because unknown does not equal unknown. This is not a quirk of the practice engine; it is the SQL standard, and it is the same in MySQL, PostgreSQL and every other database.
NULL يعني "لا قيمة هنا"، وSQL تعامله مجهولًا لا شيئًا. وكل مقارنة مع مجهول تنتج مجهولًا، لا صحيحًا ولا خاطئًا — وWHERE يبقي الصف حين يكون شرطه صحيحًا تمامًا فقط. فـphone <> '0100000001' يُسقط بصمت النزلاء الذين لا هاتف لهم البتة: فقاعدة البيانات لا تستطيع القول إن رقمهم يختلف، لأنها لا تعرف رقمهم. وphone = NULL لا يعيد شيئًا أبدًا، لأن المجهول لا يساوي المجهول. وهذه ليست غرابة في محرّك التمرين؛ بل معيار SQL، وهو نفسه في MySQL وPostgreSQL وكل قاعدة أخرى.| You write | You get | Because |
|---|---|---|
| phone = NULL | No rows, ever | Unknown is not equal to unknown |
| phone IS NULL | The rows with no phone | The only question SQL will answer about NULL |
| phone <> 'x' | The known phones that differ | The unknown ones are dropped silently |
| phone <> 'x' OR phone IS NULL | What you probably meant | You have to say it |
| COALESCE(phone, '') <> 'x' | The same, in one condition | Turn the unknown into a value first |
| NOT IN (1, 2, NULL) | No rows, ever | The same trap wearing a different hat |
The last row catches experienced people. NOT IN with a NULL anywhere in the list can never be true, because SQL cannot rule out an unknown — so a perfectly sensible-looking query returns nothing and no error.
NOT IN مع NULL في أي موضع من القائمة لا يمكن أن يصح أبدًا، لأن SQL لا تستطيع استبعاد مجهول — فيعيد استعلام يبدو معقولًا تمامًا لا شيء ولا خطأ.SELECT * أبدًا في شيفرة تطبيق: فهو يجلب أعمدة لا تحتاجها، وينكسر لحظة يضيف أحد عمودًا، ويخفي أي الأعمدة تعتمد عليها شيفرتك فعلًا. ولا بأس به أثناء الاستكشاف، ولذلك تستخدمه هذه الدروس، وهو خطأ في الاستعلام الذي يُشحن. ولا تبنِ استعلامًا أبدًا بوصل نصوص مع مدخلات مستخدم — فـ"... WHERE name = '" + typed + "'" حقن SQL، أكثر ثغرة مستغَلَّة في برمجيات الويب؛ واسم مثل ' OR '1'='1 يحوّل مرشِّحك إلى "كل شيء". وقد عرض الدرس 14 من دورة الويب الضرر. والعلاج دائمًا جملة معدّة بعناصر نائبة، لا اقتباس يدوي.
A few small things that save time. ORDER BY can take several columns, and the second only breaks ties in the first. LIMIT without ORDER BY gives you an arbitrary ten rows, not the first ten — the database is free to return them in any order, and it changes as the table grows. LIKE uses % for any run of characters and _ for exactly one. And a leading % means the database cannot use an index, so LIKE '%cairo%' reads every row — fine for six guests, not for six million.
ORDER BY يقبل عدة أعمدة، والثاني لا يفصل إلا عند التعادل في الأول. وLIMIT بلا ORDER BY يعطيك عشرة صفوف اعتباطية لا الأولى — فقاعدة البيانات حرة في إعادتها بأي ترتيب، وهو يتغير كلما كبر الجدول. وLIKE يستخدم % لأي سلسلة محارف و_ لمحرف واحد بالضبط. و% في البداية تعني أن القاعدة لا تستطيع استخدام فهرس، فـLIKE '%cairo%' يقرأ كل صف — لا بأس لستة نزلاء، لا لستة ملايين.SELECT * FROM bookings، وأضف WHERE، وتحقق أن العدد معقول، ثم أضف الشرط التالي. فكتابة ست جمل وتشغيلها مرة تعني أن الجواب الخاطئ له ستة مشتبهين؛ والتشغيل بعد كل واحدة يعني أنك تعرف دائمًا أي سطر فعلها.Try it live / جرّب بنفسك
Check yourself / اختبر نفسك
1.
Why does WHERE phone <> '0100000001' miss the guests with no phone?
WHERE phone <> '0100000001' النزلاء بلا هاتف؟Say it explicitly: OR phone IS NULL, or use COALESCE to turn the unknown into a value first.
OR phone IS NULL، أو استخدم COALESCE لتحويل المجهول إلى قيمة أولًا.
2.
What does NOT IN (1, 2, NULL) return?
NOT IN (1, 2, NULL)؟A perfectly sensible-looking query returns nothing and no error. It is the same trap as = NULL wearing a different hat.
= NULL نفسه بقبعة أخرى.
3.
Why avoid SELECT * in application code?
SELECT * في شيفرة التطبيق؟It is fine while exploring, which is why these lessons use it, and wrong in the query that ships.
Score / النتيجة: 0 / 3
Your task / مهمتك
Write twelve queries against the guest house, each answering a question you write out in English first. Between them they must use every operator in this lesson: comparison, AND, OR, NOT, LIKE, IN, BETWEEN, IS NULL, ORDER BY with two columns, and LIMIT. Include one pair that differs only in bracketing and returns different rows. Then demonstrate the NULL trap: a query that looks right, misses rows, and its corrected version — with the row counts printed for both.
اكتب اثني عشر استعلامًا على بيت الضيافة، يجيب كل واحد سؤالًا تكتبه بالإنجليزية أولًا. وعليها معًا أن تستخدم كل مؤثر في هذا الدرس: المقارنة وAND وOR وNOT وLIKE وIN وBETWEEN وIS NULL وORDER BY بعمودين وLIMIT. وضمّنها زوجًا يختلف بالأقواس فقط ويعيد صفوفًا مختلفة. ثم اعرض فخ NULL: استعلام يبدو صحيحًا ويفوّت صفوفًا، ونسخته المصححة — مع طباعة عدد الصفوف لكليهما.
- Twelve queries, each with its English question اثنا عشر استعلامًا بسؤال إنجليزي لكل واحد
- Every operator in the lesson used at least once كل مؤثر في الدرس مستخدم مرة على الأقل
- A pair differing only in brackets, with different results زوج يختلف بالأقواس فقط بنتائج مختلفة
- The NULL trap shown and corrected, with both counts فخ NULL معروضًا ومصححًا بالعددين