Menu

Funkcje liczbowe w SQLite: ROUND, ABS, CEIL, FLOOR i matematyka

Jak liczyć w SQLite: ROUND, ABS, CEIL, FLOOR, MOD, POWER, SQRT, RANDOM i pułapka dzielenia całkowitego, na którą każdy kiedyś trafia.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

SQLite ma więcej matematyki, niż się wydaje

SQLite słynie z minimalizmu, ale ma pełny zestaw funkcji liczbowych: zaokrąglanie, wartość bezwzględną, zaokrąglanie w górę i w dół, potęgi, pierwiastki, logarytmy, trygonometrię i liczby losowe. Większość funkcji matematycznych dodano w SQLite 3.35 (2021), więc każda w miarę współczesna instalacja (dołączona do Pythona, Node, przodka WebSQL w twojej przeglądarce albo oficjalne CLI) ma je gotowe do użycia.

Krótka próbka na początek:

Sześć funkcji, jeden wiersz wyników. Reszta tej strony omawia, do czego służy każda grupa funkcji i jakie pułapki warto znać.

ROUND: funkcja, której użyjesz najczęściej

ROUND(value, digits) zaokrągla do podanej liczby miejsc po przecinku. Drugi argument jest opcjonalny: jeśli go pominiesz, dostaniesz zaokrąglenie do najbliższej liczby całkowitej (ale nadal jako wartość zmiennoprzecinkową):

Kilka rzeczy, na które warto zwrócić uwagę:

  • ROUND(3.14159) zwraca 3.0, a nie 3. Jeśli chcesz liczby całkowitej, użyj CAST(ROUND(x) AS INTEGER) albo po prostu CAST(x AS INTEGER), żeby obciąć część ułamkową.
  • SQLite zaokrągla połówki „od zera”: 2.5 daje 3, a -2.5 daje -3. Niektóre bazy stosują zaokrąglanie bankowe (połówki do parzystej), SQLite tego nie robi.
  • Argument digits może być ujemny: ROUND(1234.5, -2) zaokrągla do najbliższej setki i daje 1200.

W praktyce najczęściej napiszesz ROUND(price, 2) przy wyświetlaniu kwot.

ROUND a CAST: to nie to samo

Ludzie sięgają po CAST(x AS INTEGER), gdy chcą zaokrąglić, i się na tym przejeżdżają:

CAST obcina w stronę zera: po prostu wyrzuca część ułamkową. ROUND zaokrągla do najbliższej liczby całkowitej. Dla 2.9 różnica wynosi całą jednostkę. Wybierz tę funkcję, której zachowania naprawdę potrzebujesz.

ABS, SIGN i znak liczby

ABS(x) zwraca wartość bezwzględną. SIGN(x) zwraca -1, 0 albo 1 zależnie od znaku:

ABS to koń pociągowy, przydatny w zapytaniach typu „jak daleko od siebie są te dwie wartości”. SIGN jest rzadszy, ale przydaje się, gdy chcesz podzielić wiersze według kierunku (obciążenie a uznanie, zysk a strata) bez jawnego CASE.

CEIL, FLOOR i TRUNC

Te funkcje dają wartości całkowite bez zaokrąglania do najbliższej. CEIL zawsze idzie w górę, FLOOR zawsze w dół, a TRUNC zawsze w stronę zera:

Uważaj na liczby ujemne. FLOOR(-2.9) to -3 (dalej od zera), ale TRUNC(-2.9) to -2 (w stronę zera). Przy liczbach ujemnych FLOOR i TRUNC dają różne wyniki, a wybór złej funkcji to klasyczny błąd o jeden.

CEILING to alias CEIL. Używaj zapisu, który lepiej ci się czyta.

Dzielenie całkowite to prawdziwa pułapka

To nie funkcja, tylko operator /, ale początkujących łapie częściej niż którakolwiek z prawdziwych funkcji matematycznych:

Gdy obie strony są liczbami całkowitymi, SQLite wykonuje dzielenie całkowite i obcina wynik. Gdy tylko jedna strona jest REAL, całe wyrażenie staje się rzeczywiste. Rozwiązanie: upewnij się, że co najmniej jeden argument jest zmiennoprzecinkowy, pisząc 2.0 zamiast 2 albo stosując rzutowanie.

Najbardziej boli to przy odwołaniach do kolumn: total_cents / 100 zwraca liczbę całkowitą. total_cents / 100.0 zwraca kwotę w dolarach, o którą naprawdę chodziło.

MOD i operator %

MOD(x, y) zwraca resztę z dzielenia x / y. Operator % robi to samo:

MOD(17, 5) i 17 % 5 zwracają 2. Reszta z dzielenia przez zero zwraca w SQLite NULL, a nie błąd, co jest nietypowe w porównaniu z większością języków. Jeśli ma to dla ciebie znaczenie, najpierw sprawdź dzielnik albo opakuj wywołanie w CASE WHEN y = 0 THEN ... END.

Forma funkcji i operatora są wymienne. Większość osób wybiera %, bo jest krótszy.

POWER, SQRT, EXP, LOG

Do potęg i pierwiastków:

Kilka uwag, na które ludzie się łapią:

  • POW to alias POWER.
  • LOG(x) w SQLite ma podstawę 10. LN(x) to logarytm naturalny. LOG(b, x) z dwoma argumentami to logarytm o podstawie b. (To różni się od wielu języków, w których log to logarytm naturalny: wygrała konwencja SQL.)
  • SQRT z liczby ujemnej zwraca NULL, a nie błąd.
  • POWER(0, 0) zwraca umownie 1.

Przydają się przy procencie składanym, przeliczaniu na decybele, liczeniu odległości, wszędzie tam, gdzie pojawia się matematyka geometryczna lub wykładnicza.

RANDOM i RANDOMBLOB

RANDOM() zwraca 64-bitową liczbę całkowitą ze znakiem, z całego jej zakresu:

Żeby dostać liczbę z przedziału, opakuj wynik w ABS (bo RANDOM() ma znak) i użyj %. Żeby dostać liczbę rzeczywistą między 0 a 1, podziel przez największą 64-bitową liczbę całkowitą. SQLite nie ma wbudowanego RAND() zwracającego wartość od 0 do 1: budujesz ją sam.

RANDOMBLOB(n) zwraca n bajtów losowych danych, przydatnych do generowania tokenów sesji albo danych testowych. Połącz z HEX(), żeby dostać napis nadający się do wyświetlenia:

Każde wywołanie daje nową wartość. Nie oczekuj, że RANDOM() zwróci dwa razy tę samą liczbę w tym samym wierszu: nawet w obrębie jednego wyrażenia każde wywołanie jest niezależne.

Wszystko razem

Mały przykład: obliczanie wartości i zaokrąglanie cen w tabeli produktów.

Kluczowy fragment to price_cents / 100.0: to .0 sprawia, że dzielenie jest rzeczywiste, a potem ROUND formatuje wynik do dwóch miejsc po przecinku. Bez tego 1299 / 100 dałoby 12, a nie 12.99.

Dalej: data i czas

Funkcje liczbowe zajmują się matematyką. Daty i godziny potrzebują własnego zestawu narzędzi: SQLite przechowuje je jako tekst, liczbę rzeczywistą albo całkowitą i daje niewielki, ale sprawny zestaw funkcji do ich parsowania, formatowania i obliczeń. O tym w następnej części.

Najczęściej zadawane pytania

Jak zaokrąglić do 2 miejsc po przecinku w SQLite?

Użyj ROUND(value, 2). Drugi argument to liczba zachowywanych miejsc po przecinku: ROUND(3.14159, 2) zwraca 3.14. Z jednym argumentem ROUND(x) zaokrągla do najbliższej liczby całkowitej, ale nadal zwraca wartość zmiennoprzecinkową, co bywa zaskoczeniem.

Czy SQLite ma CEIL i FLOOR?

Tak, od SQLite 3.35 (2021) funkcje matematyczne są wbudowane: CEIL(x), FLOOR(x), SQRT(x), POWER(x, y), LOG(x), EXP(x) i inne. W starszych wersjach nie są dostępne bez wczytania rozszerzenia matematycznego, ale większość współczesnych instalacji (Python, Node, przeglądarki) ma je włączone.

Dlaczego 5 / 2 zwraca 2 w SQLite?

Ponieważ oba argumenty są liczbami całkowitymi, SQLite wykonuje dzielenie całkowite i obcina wynik. Zamień jedną stronę na REAL (5 / 2.0 albo CAST(5 AS REAL) / 2), żeby dostać 2.5. To nie dziwactwo funkcji liczbowych, tylko zachowanie operatora / przy argumentach całkowitych.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ