Built-in funksiyalar — string, number, date, conditional
Muammodan boshlaylik
Ma'lumot bazaga yoziladi — lekin har doim "toza" holda kelmaydi. Foydalanuvchi ismini " ali " bo'sh joylar bilan kiritdi. Telefon raqamini "+998 90 123 45 67" formatida yozdi, siz esa "998901234567" kerak. Sanani "2024-01-15" dan faqat yilni olmoqchisiz.
Bularning barchasini ilovada, kod yozib hal qilish mumkin. Lekin PostgreSQL o'zida yuzdan ortiq tayyor funksiya bor — ko'pini SQL so'rovning o'zida hal qilsa bo'ladi, kod tarafga yukmasa ham.
Bu darsda eng ko'p ishlatiladigan to'rtta guruh: matn, raqam, sana, shartli funksiyalar.
Matn funksiyalari
Bo'sh joylarni tozalash — TRIM
Foydalanuvchi kiritgan matnda boshida yoki oxirida bo'sh joy qolishi odatiy holat. TRIM — shu bo'sh joylarni olib tashlaydi.
SELECT TRIM(' ali karimov '); -- 'ali karimov'
SELECT LTRIM(' ali '); -- 'ali ' (faqat chap)
SELECT RTRIM(' ali '); -- ' ali' (faqat o'ng)
Foydalanuvchi ro'yxatdan o'tganda ismni tozalash:
INSERT INTO foydalanuvchilar (ism)
VALUES (TRIM(' Ali Karimov '));
-- 'Ali Karimov' saqlanadi
Katta-kichik harf — UPPER, LOWER
Email manzillar katta-kichik harfga sezgir emas — lekin bazada ikki xil yozilishi mumkin: Ali@mail.com va ali@mail.com. Qidirishda muammo.
SELECT LOWER('Ali Karimov'); -- 'ali karimov'
SELECT UPPER('ali karimov'); -- 'ALI KARIMOV'
Email ni har doim kichik harfda saqlash:
INSERT INTO foydalanuvchilar (email)
VALUES (LOWER(TRIM(' Ali@Mail.Com ')));
-- 'ali@mail.com' saqlanadi — har doim bir xil format
Uzunlik — LENGTH
SELECT LENGTH('Salom'); -- 5
SELECT LENGTH(''); -- 0
SELECT LENGTH(NULL); -- NULL
Parol kamida 8 belgili bo'lishi kerakligini tekshirish:
SELECT * FROM foydalanuvchilar
WHERE LENGTH(parol) < 8;
-- Qisqa parollar
Kesish — SUBSTRING
Matnning bir qismini olish. Masalan, telefon raqamidan kodni ajratish:
SELECT SUBSTRING('998901234567', 1, 3); -- '998' (1-pozitsiyadan, 3 ta belgi)
SELECT SUBSTRING('998901234567' FROM 4); -- '901234567' (4-pozitsiyadan oxirigacha)
Yoki regex bilan:
SELECT SUBSTRING('Narxi: 15000 so''m' FROM '[0-9]+'); -- '15000'
Almashtirish — REPLACE
Matn ichidagi bir narsani boshqasiga almashtirish:
SELECT REPLACE('901 234 56 78', ' ', ''); -- '901234567' bo'shliqlar o'chirildi
SELECT REPLACE('ali@gmail.com', 'gmail', 'mail'); -- 'ali@mail.com'
Telefon raqamlarini standart formatga keltirish:
UPDATE foydalanuvchilar
SET telefon = REPLACE(REPLACE(telefon, ' ', ''), '-', '');
-- '90 123-45-67' → '901234567'
Birlashtirish — CONCAT va ||
SELECT CONCAT('Salom, ', 'Ali', '!'); -- 'Salom, Ali!'
SELECT 'Salom, ' || 'Ali' || '!'; -- 'Salom, Ali!' (bir xil)
-- CONCAT NULL ni e'tiborsiz qoldiradi
SELECT CONCAT('Salom, ', NULL, 'Ali'); -- 'Salom, Ali'
-- || esa NULL bilan NULL qaytaradi
SELECT 'Salom, ' || NULL || 'Ali'; -- NULL
Bu farq muhim: foydalanuvchining familiya ustuni NULL bo'lishi mumkin bo'lsa — || ishlatilsa butun natija NULL bo'ladi.
-- ✅ — familiya NULL bo'lsa ham ishlaydi
SELECT CONCAT(ism, ' ', familiya) AS toʻliq_ism FROM foydalanuvchilar;
-- ❌ — familiya NULL bo'lsa toʻliq_ism ham NULL
SELECT ism || ' ' || familiya AS toʻliq_ism FROM foydalanuvchilar;
Boshqa foydali matn funksiyalari
SELECT LEFT('Salom dunyo', 5); -- 'Salom' (chapdan 5 ta)
SELECT RIGHT('Salom dunyo', 5); -- 'dunyo' (o'ngdan 5 ta)
SELECT REVERSE('Salom'); -- 'molaS'
SELECT REPEAT('ab', 3); -- 'ababab'
SELECT LPAD('42', 5, '0'); -- '00042' (chapga 0 bilan to'ldirish)
SELECT RPAD('42', 5, '0'); -- '42000' (o'ngga 0 bilan to'ldirish)
SELECT POSITION('ali' IN 'salom ali'); -- 7 (qaysi pozitsiyada)
Raqam funksiyalari
Yaxlitlash — ROUND, CEIL, FLOOR
Uch xil yaxlitlash usuli bor — qaysi birini tanlash vaziyatga bog'liq.
SELECT ROUND(4.6); -- 5 (eng yaqin butun)
SELECT ROUND(4.4); -- 4 (eng yaqin butun)
SELECT ROUND(4.567, 2); -- 4.57 (ikki kasr)
SELECT CEIL(4.1); -- 5 (yuqoriga — har doim kattaroq butun)
SELECT CEIL(4.9); -- 5
SELECT FLOOR(4.9); -- 4 (pastga — har doim kichikroq butun)
SELECT FLOOR(4.1); -- 4
Narxni hisoblashda: soliq qo'shilganda har doim yuqoriga yaxlitlash (CEIL), chegirma berganada pastga (FLOOR).
Absolut qiymat, qoldiq, daraja
SELECT ABS(-15); -- 15 (manfiy bo'lsa ham musbat)
SELECT MOD(17, 5); -- 2 (17 ni 5 ga bo'lganda qoldiq)
SELECT POWER(2, 10); -- 1024 (2 ning 10-darajasi)
SELECT SQRT(144); -- 12 (kvadrat ildiz)
Tasodifiy raqam — RANDOM
SELECT RANDOM(); -- 0 va 1 orasida: 0.7341...
SELECT FLOOR(RANDOM() * 100) + 1; -- 1 dan 100 gacha tasodifiy butun
Sana va vaqt funksiyalari
Hozirgi vaqt
SELECT NOW(); -- 2024-04-15 14:23:45.123456+05
SELECT CURRENT_DATE; -- 2024-04-15 (faqat sana)
SELECT CURRENT_TIME; -- 14:23:45.123456+05 (faqat vaqt)
NOW() — tranzaksiya boshlanganidagi vaqt. CLOCK_TIMESTAMP() — har chaqirilganda haqiqiy joriy vaqt.
Sanadan qism ajratish — EXTRACT va DATE_PART
SELECT EXTRACT(YEAR FROM NOW()); -- 2024
SELECT EXTRACT(MONTH FROM NOW()); -- 4
SELECT EXTRACT(DAY FROM NOW()); -- 15
SELECT EXTRACT(DOW FROM NOW()); -- 1 (haftaning kuni: 0=yakshanba, 1=dushanba)
SELECT EXTRACT(HOUR FROM NOW()); -- 14
Oylik hisobot uchun — faqat oy bo'yicha filtrlash:
SELECT * FROM buyurtmalar
WHERE EXTRACT(YEAR FROM sana) = 2024
AND EXTRACT(MONTH FROM sana) = 4;
Sana formatlash — TO_CHAR
Sanani istalgan formatda matn sifatida chiqarish:
SELECT TO_CHAR(NOW(), 'DD.MM.YYYY'); -- '15.04.2024'
SELECT TO_CHAR(NOW(), 'DD-Mon-YYYY'); -- '15-Apr-2024'
SELECT TO_CHAR(NOW(), 'HH24:MI:SS'); -- '14:23:45'
SELECT TO_CHAR(NOW(), 'DD.MM.YYYY HH24:MI'); -- '15.04.2024 14:23'
Raqamni formatlash:
SELECT TO_CHAR(1234567.89, '9,999,999.99'); -- '1,234,567.89'
SELECT TO_CHAR(0.15, 'FM99%'); -- '15%'
Sana hisoblash — vaqt oralig'i
-- 30 kun qo'shish
SELECT NOW() + INTERVAL '30 days';
-- 1 oy oldin
SELECT NOW() - INTERVAL '1 month';
-- Ikkita sana orasidagi kunlar
SELECT ('2024-12-31'::DATE - '2024-01-01'::DATE); -- 365
-- Yoshni hisoblash
SELECT EXTRACT(YEAR FROM AGE('1995-06-15')); -- 29 (2024 yilga qarab)
Obuna tugash sanasini hisoblash:
UPDATE foydalanuvchilar
SET obuna_tugash = NOW() + INTERVAL '1 year'
WHERE id = 1;
Shartli funksiyalar
COALESCE — birinchi NULL bo'lmagan qiymat
COALESCE — ro'yxatdan birinchi NULL bo'lmagan qiymatni qaytaradi. NULL o'rniga standart qiymat ko'rsatishda eng ko'p ishlatiladigan funksiya.
SELECT COALESCE(NULL, NULL, 'standart'); -- 'standart'
SELECT COALESCE(NULL, 'ikkinchi', 'uchinchi'); -- 'ikkinchi'
SELECT COALESCE('birinchi', 'ikkinchi'); -- 'birinchi'
Amalda — foydalanuvchi ismi yo'q bo'lsa "Anonim" ko'rsatish:
SELECT COALESCE(ism, 'Anonim') AS koʻrinish
FROM foydalanuvchilar;
koʻrinish
-----------
Ali
Anonim ← ism NULL edi
Vali
NULLIF — ikki qiymat teng bo'lsa NULL qaytarish
NULLIF(a, b) — agar a = b bo'lsa NULL, aks holda a qaytaradi. Nolga bo'lish xatosini oldini olishda foydali:
SELECT 100 / NULLIF(0, 0); -- NULL (0 ga bo'lish o'rniga NULL)
SELECT 100 / NULLIF(5, 0); -- 20
Bo'sh satr o'rniga NULL saqlash:
UPDATE foydalanuvchilar
SET telefon = NULLIF(TRIM(telefon), '');
-- ' ' → NULL, '901234567' → '901234567'
CASE — shartli ifoda
SQL dagi if/else. Natijani shartga qarab o'zgartirish:
SELECT
nomi,
narx,
CASE
WHEN narx < 500000 THEN 'Arzon'
WHEN narx < 2000000 THEN 'O''rta'
ELSE 'Qimmat'
END AS toifa
FROM mahsulotlar;
nomi │ narx │ toifa
-------------+-----------+---------
Sichqon │ 150 000 │ Arzon
Klaviatura │ 350 000 │ Arzon
Headset │ 450 000 │ Arzon
Noutbuk │ 5 000 000 │ Qimmat
Monitor │ 2 800 000 │ Qimmat
Qisqa shakl — bitta ustunni tekshirish:
SELECT holat,
CASE holat
WHEN 'pending' THEN 'Kutilmoqda'
WHEN 'processing' THEN 'Jarayonda'
WHEN 'delivered' THEN 'Yetkazildi'
ELSE 'Boshqa'
END AS holat_uz
FROM buyurtmalar;
Tez-tez uchraydigan xatolar
|| bilan NULL qo'shish:
-- ❌ — familiya NULL bo'lsa natija NULL
SELECT ism || ' ' || familiya FROM foydalanuvchilar;
-- ✅ — COALESCE bilan NULL ni bo'sh satrga aylantirish
SELECT ism || ' ' || COALESCE(familiya, '') FROM foydalanuvchilar;
-- Yoki CONCAT — NULL ni avtomatik e'tiborsiz qoldiradi
SELECT CONCAT(ism, ' ', familiya) FROM foydalanuvchilar;
Sana filtrlashda indeksni buzish:
-- ❌ — EXTRACT hisoblash kerak, indeks ishlamaydi
WHERE EXTRACT(YEAR FROM sana) = 2024;
-- ✅ — to'g'ridan-to'g'ri sana oralig'i, indeks ishlaydi
WHERE sana >= '2024-01-01' AND sana < '2025-01-01';
EXTRACT va TO_CHAR funksiyalar sana ustunini o'zgartiradi — indeks esa asl ustun bo'yicha qurilgan, shu sababli ishlatilmaydi. Sana oralig'i bilan filtr — aniqroq va tezroq.
Xulosa
PostgreSQL built-in funksiyalari ma'lumotni bazaning o'zida tozalash, formatlash, hisoblash imkonini beradi.
Matn: TRIM, LOWER/UPPER, LENGTH, SUBSTRING, REPLACE, CONCAT
Raqam: ROUND, CEIL, FLOOR, ABS, MOD, POWER
Sana: NOW, EXTRACT, TO_CHAR, AGE, INTERVAL
Shartli: COALESCE, NULLIF, CASE
Bir qoida esda tuting: funksiyani WHERE da ustun ustida ishlatish indeksni o'chiradi. Mumkin bo'lsa, ustunni o'zgartirmay, qiymatni o'zgartiring — yoki generated column ishlating.
Keyingi dars
31-dars: PL/pgSQL — asoslar, o'zgaruvchilar, shartlar, sikllar