WHERE מסננת שורות אחת אחת
SELECT בלי WHERE מחזיר כל שורה בטבלה. זה רק לעיתים רחוקות מה שרוצים. WHERE מאפשרת לשמור רק את השורות שמתאימות לתנאי: SQLite עובר על הטבלה, בודק את התנאי מול כל שורה, ושומר את אלה שבהן הוא אמת.
שלוש שורות חוזרות: Neuromancer, Hyperion ו-The Martian. התנאי year > 1980 נבדק מול כל שורה, ורק ההתאמות שרדו.
המודל המנטלי: WHERE היא מסנן שיושב בין FROM לבין העמודות שבוחרים. כל מה שמתקבל כאמת עובר.
אופרטורי השוואה
הבסיס עובד כמו שהייתם מצפים:
= לשוויון, != או <> ל"לא שווה", ו-<, <=, >, >= לסדר. השוואות מחרוזות משתמשות באותם אופרטורים: author = 'Asimov' מתאים בדיוק, תו אחר תו.
דבר אחד שכדאי לדעת: SQL משתמש בגרשיים בודדים לליטרלים של מחרוזות. מירכאות כפולות הן למזהים (שמות של עמודות או טבלאות). WHERE author = "Asimov" עשוי לעבוד ב-SQLite מסיבות היסטוריות, אבל זה לא נייד ויכול להתנהג לא נכון בשקט כשה"מחרוזת" במקרה זהה לשם של עמודה. היצמדו לגרשיים בודדים.
AND, OR וסוגריים
שאילתות אמיתיות בדרך כלל משלבות תנאים. AND דורש ששני הצדדים יהיו אמת. OR דורש לפחות אחד:
השאילתה הראשונה מסננת ספרים חדשים וגם קצרים. השנייה שולפת ספרים של אחד משני הסופרים.
כשמערבבים AND ו-OR, סדר הקדימויות נושך אנשים. AND קושר חזק יותר מ-OR, כך ש:
נקרא כ-Herbert OR (Gibson AND year > 1980): כל ספר של Herbert בלי קשר לשנה, ועוד ספרים של Gibson אחרי 1980. כנראה לא מה שהתכוונתם. עטפו את הכוונה שלכם בסוגריים:
כשיש ספק, הוסיפו סוגריים. לאופטימייזר של השאילתות זה לא משנה, והאדם הבא שיקרא את זה יודה לכם.
NULL לא מתנהג כמו ערך
זו המלכודת של פסוקית WHERE שתופסת כל אחד פעם אחת. NULL ב-SQL פירושו "לא ידוע", ואי אפשר להשוות ערכים לא ידועים. column = NULL הוא לא שקר: הוא NULL, ו-WHERE מתייחסת לזה כ"דלג על השורה הזו".
IS NULL ו-IS NOT NULL הם האופרטורים היחידים שבודקים NULL ישירות. חרטו אותם באצבעות: כל השוואה אחרת עם NULL מחזירה NULL וזורקת שורות בשקט.
אותו כלל חל על שלילה. WHERE author != 'Asimov' לא מחזיר שורות שבהן author IS NULL, כי גם NULL != 'Asimov' הוא NULL. אם אתם רוצים לכלול ערכי NULL, בקשו אותם במפורש: WHERE author != 'Asimov' OR author IS NULL.
IN ו-BETWEEN: קיצורי דרך שתשתמשו בהם כל יום
IN בודק שייכות לרשימה. זו דרך נקייה יותר לכתוב שרשרת של OR:
BETWEEN בודק טווח, כולל בשני הקצוות:
year BETWEEN 1980 AND 2000 זהה ל-year >= 1980 AND year <= 2000, רק קצר יותר. דבר אחד לזכור: שני הגבולות כלולים. אם רוצים גבולות לא כוללים, כתבו את ההשוואות במלואן.
הערה קצרה על IN ו-NULL: WHERE column NOT IN (1, 2, NULL) לעולם לא יחזיר שורות, כי השוואה של כל דבר ל-NULL מניבה NULL. סננו ערכי NULL מהרשימה שלכם, או טפלו בהם בנפרד עם IS NULL.
LIKE להתאמת תבניות
LIKE מבצע התאמת תבניות של מחרוזות עם שני תווים כלליים:
%מתאים לכל רצף של תווים (כולל רצף ריק)._מתאים לתו אחד בדיוק.
כברירת מחדל, LIKE של SQLite לא רגיש לאותיות גדולות וקטנות באותיות ASCII: 'Dune' LIKE 'dune' הוא אמת. זה מפתיע אם אתם מגיעים מ-Postgres, שם LIKE רגיש לאותיות ו-ILIKE היא הגרסה שלא רגישה. (ל-SQLite אין ILIKE.)
אם אתם צריכים התאמה רגישה לאותיות, יש שתי אפשרויות. להחליף את ה-pragma הגלובלי:
PRAGMA case_sensitive_like = ON;
או להשתמש ב-GLOB, שתמיד רגיש לאותיות ומשתמש בתווים כלליים בסגנון Unix (* לכל רצף, ? לתו אחד):
GLOB 'd*' לא היה מתאים כאן לכלום: אותיות גדולות וקטנות משנות.
סינון תאריכים
SQLite שומר תאריכים כטקסט (בדרך כלל YYYY-MM-DD או ISO 8601 מלא), כלומר השוואות מחרוזות עובדות במקרה גם כהשוואות תאריכים, כל עוד נצמדים לפורמט ISO:
מכיוון ש-'2024-06-01' < '2024-11-08' הוא אמת גם כמחרוזות וגם כתאריכים, השאילתות האלה עושות את מה שהייתם מצפים. אם שומרים תאריכים בכל פורמט אחר ('15/01/2024', 'Jan 15 2024'), ההשוואות יפיקו בשקט תוצאות שגויות. תמיד השתמשו ב-ISO 8601: העצמי העתידי שלכם יהיה מרוצה.
לחישובי תאריכים מסובכים יותר (חילוץ השנה, השוואה ל"היום"), ל-SQLite יש את הפונקציות date(), strftime() ו-julianday(). נכסה אותן בפרק על תאריכים ושעות.
מחברים הכול יחד
שאילתה שמשתמשת בכמה מאלה בבת אחת:
קראו אותה שורה אחר שורה: שומרים שורות עם שנה ידועה, בטווח, של אחד משני סופרים או ארוכות מספיק, ושאינן טיוטה. זו פסוקית WHERE שעושה את מה שהיא עושה הכי טוב: משלבת תנאים קטנים וקריאים לסינונים מדויקים.
שני הרגלים ששווה לשמור:
- הזיחו כל תנאי בשורה משלו. פסוקיות
WHEREארוכות הופכות לבלתי קריאות מהר כשורה ענקית אחת. - כתבו הערה על הכוונה כשהתנאי לא ברור מאליו.
-- exclude draftsהוא ביטוח זול.
הבא בתור: אופרטורים ו-NULL לעומק
פסוקית WHERE היא בעיקר אופרטורים שמופעלים על עמודות, ו-NULL משנה בשקט את ההתנהגות של כל אופרטור. הדף הבא נכנס לעומק לסט האופרטורים של SQLite: חשבון, שרשור מחרוזות עם ||, משפחת ה-IS, לוגיקה תלת ערכית, כדי שההפתעות יפסיקו להיות הפתעות.
שאלות נפוצות
איך פסוקית WHERE עובדת ב-SQLite?
WHERE מסננת שורות משאילתה על ידי בדיקת תנאי מול כל שורה. שורות שבהן התנאי מתקבל כאמת נשמרות. שורות שבהן הוא שקר או NULL נזרקות. היא באה מיד אחרי FROM: SELECT ... FROM table WHERE condition.
איך משלבים כמה תנאים בפסוקית WHERE ב-SQLite?
השתמשו ב-AND וב-OR. AND דורש ששני הצדדים יהיו אמת. OR צריך רק אחד. AND קושר חזק יותר מ-OR, ולכן עטפו תנאים מעורבים בסוגריים כדי להיות מפורשים: WHERE (a OR b) AND c.
למה WHERE column = NULL לא עובד ב-SQLite?
NULL פירושו "לא ידוע", ולכן כל השוואה עם = או != מחזירה NULL במקום אמת או שקר, ושורות נשמרות רק כשהתנאי הוא אמת. השתמשו במקום זאת ב-IS NULL וב-IS NOT NULL. אלה האופרטורים היחידים שבודקים NULL ישירות.
האם LIKE בפסוקית WHERE של SQLite רגיש לאותיות גדולות וקטנות?
כברירת מחדל, LIKE לא רגיש לאותיות גדולות וקטנות בתווי ASCII: 'Hello' LIKE 'hello' הוא אמת. לרגישות מלאה, הגדירו PRAGMA case_sensitive_like = ON; או השתמשו ב-GLOB, שתמיד רגיש לאותיות ומשתמש בתווים כלליים בסגנון Unix (* ו-?).