ל-SQLite יש יותר מתמטיקה ממה שהייתם מצפים
SQLite ידועה במינימליזם שלה, אבל היא מגיעה עם סט מלא של פונקציות מספריות: עיגול, ערך מוחלט, עיגול כלפי מעלה וכלפי מטה, חזקות, שורשים, לוגריתמים, טריגונומטריה ומספרים אקראיים. רוב הפונקציות המתמטיות נוספו ב-SQLite 3.35 (2021), כך שכל התקנה מודרנית במידה סבירה, זו שמגיעה עם Python, עם Node, עם האב הקדמון WebSQL של הדפדפן שלכם או עם ה-CLI הרשמי, כוללת אותן ומוכנה לעבודה.
הנה טעימה מהירה לפני שנצלול פנימה:
שש פונקציות, שורה אחת של תוצאות. שאר העמוד עובר על מה שכל משפחה עושה ועל המלכודות שכדאי להכיר.
ROUND: זו שתשתמשו בה הכי הרבה
ROUND(value, digits) מעגל למספר נתון של ספרות אחרי הנקודה. הארגומנט השני אופציונלי: השמיטו אותו ותקבלו עיגול למספר השלם הקרוב (אבל עדיין כערך נקודה צפה):
כמה דברים לשים לב אליהם:
ROUND(3.14159)מחזיר3.0, לא3. אם אתם רוצים מספר שלם, השתמשו ב-CAST(ROUND(x) AS INTEGER), או פשוט ב-CAST(x AS INTEGER)לקטיעה.- SQLite משתמשת ב"עיגול חצי הרחק מאפס":
2.5מתעגל ל-3, ו--2.5מתעגל ל--3. יש מסדי נתונים שמשתמשים בעיגול בנקאי (חצי לזוגי הקרוב); SQLite לא. - הארגומנט
digitsיכול להיות שלילי:ROUND(1234.5, -2)מעגל למאה הקרובה ונותן1200.
בפועל תכתבו ROUND(price, 2) להצגת סכומי כסף יותר מכל דבר אחר.
ROUND מול CAST: הם שונים
אנשים משתמשים ב-CAST(x AS INTEGER) כשהם מתכוונים לעגל, ונכווים:
CAST קוטע לכיוון אפס: הוא פשוט זורק את החלק השברי. ROUND מעגל למספר השלם הקרוב. עבור 2.9 ההבדל ביניהם הוא יחידה שלמה. בחרו את זה שההתנהגות שלו היא מה שאתם באמת רוצים.
ABS, SIGN והסימן של מספר
ABS(x) מחזיר את הערך המוחלט. SIGN(x) מחזיר -1, 0 או 1 לפי הסימן:
ABS הוא סוס העבודה, שימושי לשאילתות של "כמה רחוקים שני הערכים האלה זה מזה". SIGN פחות נפוץ, אבל שימושי כשרוצים לקבץ שורות לפי כיוון (חובה מול זכות, רווח מול הפסד) בלי CASE מפורש.
CEIL, FLOOR ו-TRUNC
אלה נותנים ערכים שלמים בלי עיגול לקרוב ביותר. CEIL תמיד עולה, FLOOR תמיד יורד, TRUNC תמיד הולך לכיוון אפס:
שימו לב למקרים השליליים. FLOOR(-2.9) הוא -3 (רחוק יותר מאפס), אבל TRUNC(-2.9) הוא -2 (לכיוון אפס). במספרים שליליים FLOOR ו-TRUNC לא מסכימים, ובחירה בלא נכון היא באג off-by-one קלאסי.
CEILING הוא שם חלופי ל-CEIL. השתמשו בכתיב שנראה לכם קריא יותר.
חילוק בשלמים הוא המלכודת האמיתית
זו לא פונקציה, זה האופרטור /, אבל הוא מכשיל מתחילים יותר מכל אחת מהפונקציות המתמטיות עצמן:
כששני הצדדים הם מספרים שלמים, SQLite מבצעת חילוק בשלמים וקוטעת. ברגע שצד אחד הוא REAL, כל הביטוי הופך לממשי. הפתרון הוא לוודא שלפחות אופרנד אחד הוא מספר עשרוני, בין אם על ידי כתיבת 2.0 במקום 2 ובין אם על ידי המרה.
זה עוקץ הכי חזק עם הפניות לעמודות: total_cents / 100 מחזיר מספר שלם. total_cents / 100.0 מחזיר את הסכום בדולרים שבאמת רציתם.
MOD והאופרטור %
MOD(x, y) מחזיר את השארית של x / y. האופרטור % עושה את אותו דבר:
MOD(17, 5) ו-17 % 5 מחזירים שניהם 2. מודולו באפס מחזיר NULL ב-SQLite: הוא לא זורק שגיאה, וזה חריג בהשוואה לרוב השפות. אם זה חשוב לכם, בדקו קודם את המחלק או עטפו את הקריאה ב-CASE WHEN y = 0 THEN ... END.
צורת הפונקציה וצורת האופרטור ניתנות להחלפה. רוב האנשים משתמשים ב-% כי הוא קצר יותר.
POWER, SQRT, EXP, LOG
לחזקות ולשורשים:
כמה הערות שתופסות אנשים:
POWהוא שם חלופי ל-POWER.LOG(x)ב-SQLite הוא בבסיס 10.LN(x)הוא הלוגריתם הטבעי.LOG(b, x)עם שני ארגומנטים הוא לוגריתם בבסיסb. (זה שונה מהרבה שפות שבהןlogהוא הלוגריתם הטבעי; מוסכמת ה-SQL ניצחה.)SQRTשל מספר שלילי מחזירNULL, לא שגיאה.POWER(0, 0)מחזיר1לפי מוסכמה.
אלה שימושיות לריבית דריבית, לנרמול לדציבלים, לחישוב מרחקים: בכל מקום שבו מופיעה מתמטיקה גיאומטרית או מעריכית.
RANDOM ו-RANDOMBLOB
RANDOM() מחזירה מספר שלם של 64 ביט עם סימן, בכל מקום בטווח המלא שלו:
כדי לקבל מספר בטווח מסוים, עטפו עם ABS (כי RANDOM() כולל סימן) והשתמשו ב-%. כדי לקבל מספר ממשי בין 0 ל-1, חלקו במספר השלם המקסימלי של 64 ביט. ל-SQLite אין RAND() מובנית שמחזירה ערך בין 0 ל-1: בונים אותה בעצמכם.
RANDOMBLOB(n) מחזירה n בתים של נתונים אקראיים, שימושי לייצור טוקנים של סשן או נתוני בדיקה. שלבו עם HEX() כדי לקבל מחרוזת שאפשר להדפיס:
כל קריאה מייצרת ערך חדש. אל תצפו ש-RANDOM() תחזיר את אותו מספר פעמיים באותה שורה: גם בתוך ביטוי אחד, כל הפעלה עצמאית.
לחבר את הכול יחד
דוגמה מעשית קטנה: חישוב מרחקים ועיגול מחירים בטבלת מוצרים.
ה-price_cents / 100.0 הוא החלק החשוב: ה-.0 הזה הופך את החילוק לממשי, ואז ROUND מעצב אותו לשתי ספרות אחרי הנקודה. בלעדיו, 1299 / 100 היה נותן 12, לא 12.99.
הצעד הבא: תאריך ושעה
פונקציות מספריות מטפלות במתמטיקה. תאריכים ושעות צריכים ארגז כלים משלהם: SQLite שומרת אותם כטקסט, כמספר ממשי או כמספר שלם, ונותנת סט קטן אבל מסוגל של פונקציות לפענוח, לעיצוב ולחישובים עליהם. זה מה שמגיע בעמוד הבא.
שאלות נפוצות
איך מעגלים לשתי ספרות אחרי הנקודה ב-SQLite?
השתמשו ב-ROUND(value, 2). הארגומנט השני הוא מספר הספרות אחרי הנקודה שרוצים לשמור: ROUND(3.14159, 2) מחזיר 3.14. עם ארגומנט אחד, ROUND(x) מעגל למספר השלם הקרוב אבל עדיין מחזיר ערך נקודה צפה, וזה מפתיע אנשים.
יש ב-SQLite את CEIL ו-FLOOR?
כן, מאז SQLite 3.35 (2021) הפונקציות המתמטיות מובנות: CEIL(x), FLOOR(x), SQRT(x), POWER(x, y), LOG(x), EXP(x) וחברותיהן. בגרסאות ישנות יותר הן לא זמינות אלא אם טוענים את הרחבת המתמטיקה; רוב ההתקנות המודרניות (Python, Node, דפדפנים) מגיעות איתן כשהן מופעלות.
למה 5 / 2 מחזיר 2 ב-SQLite?
כי שני האופרנדים הם מספרים שלמים, ולכן SQLite מבצעת חילוק בשלמים וקוטעת את התוצאה. המירו צד אחד ל-REAL, 5 / 2.0 או CAST(5 AS REAL) / 2, כדי לקבל 2.5. זו לא מוזרות של פונקציה מספרית; כך האופרטור / מתנהג עם ארגומנטים שלמים.