Number funksiyalar — ROUND, CEIL, FLOOR, MOD, ABS

~10 daq · MySQL · Funksiyalar

Muammodan boshlaylik

Hisob-kitoblarda doim savollar chiqadi:

  • 15% chegirmadan keyin narx 2 635 000.5 bo'ldi — tiyinlar bilan nima qilamiz?
  • 47 ta mahsulot, sahifada 10 ta — nechta sahifa?
  • Yetkazib berish: har boshlangan kilogramm uchun 5 000 so'm — 2.3 kg uchun qancha?
  • Narx 990 ga tugasin: 2 635 000 → 2 634 990

Bularning hammasi uchun SQL da tayyor funksiyalar bor.


Yaxlitlash: ROUND, CEIL, FLOOR, TRUNCATE

SELECT ROUND(2.5), ROUND(2.4), ROUND(-2.5);   -- 3, 2, -3
SELECT ROUND(3.14159, 2);                      -- 3.14
SELECT ROUND(1234567, -3);                     -- 1235000 — mingga yaxlitlash

ROUND(son, n):

  • n > 0 — verguldan keyin n xona
  • n < 0 — verguldan oldin: -3 → minglar
SELECT CEIL(2.1), CEIL(2.9), CEIL(-2.1);       -- 3, 3, -2  — yuqoriga
SELECT FLOOR(2.1), FLOOR(2.9), FLOOR(-2.1);    -- 2, 2, -3  — pastga
SELECT TRUNCATE(2.97, 1), TRUNCATE(2.97, 0);   -- 2.9, 2    — kesish, yaxlitlamasdan
Funksiya 2.5 2.4 -2.5 Qachon
ROUND 3 2 -3 Odatiy yaxlitlash
CEIL 3 3 -2 "Har boshlangan ..." — sahifalar, kilogrammlar
FLOOR 2 2 -3 "To'liq ..." — yoshi, to'liq oylar
TRUNCATE 2 2 -2 Shunchaki kasr qismini tashlash

Amaliy misollar

-- Sahifalar soni
SELECT CEIL(COUNT(*) / 10) AS sahifalar FROM mahsulotlar;

-- Yetkazish: har boshlangan kg uchun 5000 so'm
SELECT CEIL(2.3) * 5000;   -- 15000

-- 15% chegirma, butun so'mga yaxlitlab
SELECT nom, narx, ROUND(narx * 0.85) AS chegirmali FROM mahsulotlar;

-- Narx 1000 ga yaxlitlangan
SELECT ROUND(narx * 0.85, -3) FROM mahsulotlar;

[!WARNING] FLOAT/DOUBLE ustunlarda ROUND kutilmagan natija berishi mumkin: ROUND(2.675, 2) → 2.67 (2.68 emas), chunki 2.675 ikkilik tizimda 2.67499999... bo'lib saqlanadi. DECIMAL da bu muammo yo'q (4-dars). Pul — faqat DECIMAL yoki butun son.


Qoldiq: MOD va %

SELECT MOD(17, 5), 17 % 5;   -- 2, 2
-- Juft/toq ID lar (A/B test uchun guruhlash)
SELECT id, IF(id % 2 = 0, 'A', 'B') AS guruh FROM mijozlar;

-- Har 10-buyurtmaga sovg'a
SELECT id FROM buyurtmalar WHERE id % 10 = 0;

Mutlaq qiymat va ishora: ABS, SIGN

SELECT ABS(-150), ABS(150);           -- 150, 150
SELECT SIGN(-5), SIGN(0), SIGN(5);    -- -1, 0, 1
-- Ombor va hisob o'rtasidagi farqlar (yo'nalishidan qat'i nazar)
SELECT sku, ABS(o.soni - b.soni) AS farq
FROM ombor_hisobi o JOIN buxgalteriya b USING (sku)
WHERE o.soni <> b.soni;

Daraja, ildiz, logarifm

SELECT POWER(2, 10), POW(1.12, 3);   -- 1024, 1.404928
SELECT SQRT(144);                     -- 12
SELECT LOG10(1000), LN(EXP(1));       -- 3, 1

Murakkab foiz — 12% yillik, 3 yil:

SELECT ROUND(10000000 * POWER(1.12, 3)) AS jami;   -- 14049280

Tasodifiy son: RAND

SELECT RAND();                          -- 0.6543... (0 dan 1 gacha)
SELECT FLOOR(1 + RAND() * 6);           -- 1 dan 6 gacha — o'yin kubigi

Tasodifiy 3 ta mahsulot ("Sizga yoqishi mumkin"):

SELECT nom FROM mahsulotlar ORDER BY RAND() LIMIT 3;

[!WARNING] ORDER BY RAND() har bir qatorga tasodifiy son berib, butun jadvalni saralaydi. 100 qatorda normal, 1 000 000 qatorda — juda sekin. Katta jadvallarda tasodifiy id oralig'ini tanlash yoki ilovada tanlash yaxshiroq.


Eng katta / kichik: GREATEST, LEAST

MAX/MIN — qatorlar orasida. GREATEST/LEAST — bir qatordagi qiymatlar orasida:

SELECT GREATEST(10, 25, 7), LEAST(10, 25, 7);   -- 25, 7

-- Chegirma narxning 50% idan oshmasin
SELECT nom, narx - LEAST(narx * 0.5, 2000000) AS yakuniy FROM mahsulotlar;

-- Ombordagi soni manfiy bo'lib qolmasin
UPDATE mahsulotlar SET soni = GREATEST(soni - 3, 0) WHERE id = 1;

Biror qiymat NULL bo'lsa — natija NULL.


Butun bo'lish: DIV

SELECT 17 / 5, 17 DIV 5;   -- 3.4000, 3
-- Daqiqalarni soat va daqiqaga
SELECT 135 DIV 60 AS soat, 135 % 60 AS daqiqa;   -- 2, 15

Nolga bo'lish

SELECT 10 / 0;   -- NULL (va ogohlantirish)

MySQL xato bermaydi, NULL qaytaradi (strict mode da INSERT/UPDATE ichida esa xato). Konversiya foizi hisobida:

SELECT
    toifa_id,
    SUM(sotilgan) / NULLIF(SUM(korilgan), 0) * 100 AS konversiya
FROM ...

NULLIF(x, 0) — x nol bo'lsa NULL qaytaradi, bo'linma ham NULL bo'ladi, xato yo'q (28-dars).


Nima uchun shunday?

Nima uchun ROUND(2.5) = 3, lekin ba'zi dasturlash tillarida round(2.5) = 2?

Yaxlitlashning bir nechta qoidasi bor. MySQL DECIMAL uchun "yarmini noldan uzoqqa" (2.5 → 3, -2.5 → -3) qoidasini ishlatadi — maktabda o'rgatilgani. Python, .NET esa "bankir yaxlitlashi" ni (yarmi — eng yaqin juftga: 2.5 → 2, 3.5 → 4) ishlatadi, chunki ko'p hisobda u xatolarni jamlamaydi. Ilova va baza turli qoidani ishlatsa — tiyin farqlari chiqadi. Pul bilan ishlaganda yaxlitlashni bir joyda qiling.


Xulosa

Eslab qoling:

  • ROUND(x, n) — odatiy; n < 0 — o'nlik/minglarga
  • CEIL — yuqoriga ("har boshlangan"), FLOOR — pastga, TRUNCATE — kesish
  • % / MOD — qoldiq; DIV — butun bo'linma
  • ABS, POWER, SQRT — matematik
  • GREATEST / LEAST — bir qatordagi qiymatlar orasida (MAX/MIN — qatorlar orasida)
  • ORDER BY RAND() — katta jadvalda sekin
  • Nolga bo'lish → NULL; NULLIF(x, 0) bilan himoya

Keyingi dars

27-dars: Date funksiyalar — NOW, DATE_FORMAT, DATEDIFF, DATE_ADD