- Database tushunchalari
- PostgreSQL Ma'lumot Turlari
- Asosiy SQL buyruqlari
- Primary Key va Constraints
- Amaliy mashg'ulot
Ushbu darsda siz quyidagilarni o'rganasiz:
✅ Database, Table, Column, Row tushunchalarini
✅ PostgreSQL'ning barcha ma'lumot turlarini
✅ Asosiy CRUD operatsiyalarini (Create, Read, Update, Delete)
✅ Primary Key va Constraints'larni
✅ Real proyektlarda qo'llash usullarini
PostgreSQL'da ma'lumotlar ierarxik tuzilmada saqlanadi:
graph TB
A[PostgreSQL Server] --> B[Database 1: university]
A --> C[Database 2: shop]
A --> D[Database 3: blog]
B --> E[Schema: public]
E --> F[Table: students]
E --> G[Table: courses]
E --> H[Table: grades]
F --> I[Columns]
F --> J[Rows qatorlar]
I --> K[id: INTEGER]
I --> L[name: VARCHAR]
I --> M[age: INTEGER]
J --> N[Row 1: Ali, 20]
J --> O[Row 2: Vali, 21]
style A fill:#336791,color:#fff,stroke:#1e40af,stroke-width:4px
style B fill:#10b981,color:#fff,stroke:#059669,stroke-width:3px
style C fill:#10b981,color:#fff,stroke:#059669,stroke-width:3px
style D fill:#10b981,color:#fff,stroke:#059669,stroke-width:3px
style E fill:#3b82f6,color:#fff,stroke:#1d4ed8,stroke-width:2px
style F fill:#f59e0b,color:#fff,stroke:#d97706,stroke-width:2px
style G fill:#f59e0b,color:#fff,stroke:#d97706,stroke-width:2px
style H fill:#f59e0b,color:#fff,stroke:#d97706,stroke-width:2px
Database — bu ma'lumotlarni tartibli saqlash uchun katta konteyner.
Real hayotdan misol:
Tasavvur qiling, sizda kutubxona bor:
- 📚 Database = Butun kutubxona binosi
- 📖 Table = Har xil bo'limlar (roman, ilmiy, she'riyat)
- 📄 Row = Har bir kitob
- 🏷️ Column = Kitob ma'lumotlari (nom, muallif, yil)
Table — database ichidagi aniq bir turdagi ma'lumotlar to'plami.
Misol:
-- University database ichida
Tables:
├── students -- Talabalar haqida
├── teachers -- O'qituvchilar haqida
├── courses -- Kurslar haqida
└── enrollments -- Ro'yxatga olishColumn — jadvaldagi ma'lumot turi va xususiyati.
Misol: students jadvali
| Column nomi | Ma'lumot turi | Ta'rif |
|---|---|---|
id |
INTEGER | Talabaning noyob raqami |
first_name |
VARCHAR(50) | Ismi (50 belgigacha) |
last_name |
VARCHAR(50) | Familiyasi |
email |
VARCHAR(100) | Email manzili |
age |
INTEGER | Yoshi |
gpa |
DECIMAL(3,2) | O'rtacha baho (0.00-4.00) |
enrolled_date |
DATE | Ro'yxatga olingan sana |
Row — jadvaldagi bitta to'liq yozuv.
Misol:
┌────┬────────────┬───────────┬──────────────────────┬─────┬──────┬───────────────┐
│ id │ first_name │ last_name │ email │ age │ gpa │ enrolled_date │
├────┼────────────┼───────────┼──────────────────────┼─────┼──────┼───────────────┤
│ 1 │ Ali │ Valiyev │ ali@university.uz │ 20 │ 3.85 │ 2024-09-01 │ ← Bitta row
└────┴────────────┴───────────┴──────────────────────┴─────┴──────┴───────────────┘
-- Database yaratish
CREATE DATABASE university;
-- Database'ga ulanish
\c university
-- Table yaratish
CREATE TABLE students (
id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INTEGER CHECK (age >= 16 AND age <= 100),
gpa DECIMAL(3,2) CHECK (gpa >= 0.00 AND gpa <= 4.00),
enrolled_date DATE DEFAULT CURRENT_DATE
);
-- Ma'lumot qo'shish (Row yaratish)
INSERT INTO students (first_name, last_name, email, age, gpa)
VALUES
('Ali', 'Valiyev', 'ali@university.uz', 20, 3.85),
('Madina', 'Karimova', 'madina@university.uz', 19, 3.92),
('Bekzod', 'Tursunov', 'bekzod@university.uz', 21, 3.67);
-- Natijani ko'rish
SELECT * FROM students;Natija:
id | first_name | last_name | email | age | gpa | enrolled_date
----+------------+-----------+----------------------+-----+------+---------------
1 | Ali | Valiyev | ali@university.uz | 20 | 3.85 | 2026-01-22
2 | Madina | Karimova | madina@university.uz | 19 | 3.92 | 2026-01-22
3 | Bekzod | Tursunov | bekzod@university.uz | 21 | 3.67 | 2026-01-22
PostgreSQL 90+ ma'lumot turini qo'llab-quvvatlaydi. Keling, eng muhimlarini ko'rib chiqamiz.
PostgreSQL'da eng ko'p ishlatiladigan ma'lumot turlari:
| Kategoriya | Ma'lumot Turlari | Qo'llanilishi |
|---|---|---|
| 🔢 Sonlar | INTEGER, BIGINT, SMALLINT |
ID, sonlar, miqdorlar |
DECIMAL, NUMERIC |
Pul, aniq hisob-kitoblar | |
REAL, DOUBLE PRECISION |
Ilmiy hisob-kitoblar | |
SERIAL, BIGSERIAL |
Avtomatik ID | |
| 📝 Matn | CHAR(n) |
Aniq uzunlik (kod, telefon) |
VARCHAR(n) |
O'zgaruvchan uzunlik (ism, email) | |
TEXT |
Cheksiz matn (maqolalar, izohlar) | |
| 📅 Sana/Vaqt | DATE |
Faqat sana (tug'ilgan kun) |
TIME |
Faqat vaqt (ochilish vaqti) | |
TIMESTAMP |
Sana + vaqt (buyurtma vaqti) | |
TIMESTAMPTZ |
Vaqt zonasi bilan | |
INTERVAL |
Vaqt oralig'i (3 kun, 2 soat) | |
| ✔️ Boolean | BOOLEAN |
TRUE/FALSE/NULL |
| 📦 JSON | JSON, JSONB |
Strukturalangan ma'lumotlar |
| 🎯 Maxsus | UUID |
Noyob identifikator |
ARRAY |
Massivlar | |
INET |
IP manzil | |
MONEY |
Pul (valyuta) | |
BYTEA |
Binary data |
Qisqa tavsiya:
- 💰 Pul uchun →
DECIMAL(10, 2) - 🔢 ID uchun →
SERIALyokiBIGSERIAL - 📝 Ism uchun →
VARCHAR(100) - 📄 Maqola uchun →
TEXT - 📅 Sana uchun →
DATEyokiTIMESTAMP - ✔️ Holat uchun →
BOOLEAN
INTEGER (yoki INT) — eng ko'p ishlatiladigan sonli tur.
**
Xususiyatlari:**
- Hajm: 4 bayt
- Oraliq: -2,147,483,648 dan 2,147,483,647 gacha
- Ishlatilishi: ID, yoshlar, sonlar
Misollar:
-- Oddiy misol
CREATE TABLE products (
id INTEGER,
quantity INTEGER, -- Mahsulot soni
price INTEGER -- Narx (butun son)
);
-- Real misol: Do'kon
CREATE TABLE products (
product_id INTEGER PRIMARY KEY,
name VARCHAR(100),
quantity_in_stock INTEGER DEFAULT 0,
times_sold INTEGER DEFAULT 0,
category_id INTEGER
);
-- Ma'lumot qo'shish
INSERT INTO products VALUES
(1, 'Laptop', 50, 120, 1),
(2, 'Mouse', 200, 450, 1),
(3, 'Keyboard', 75, 230, 1);
-- Ko'rish
SELECT * FROM products;BIGINT — juda katta butun sonlar uchun.
Xususiyatlari:
- Hajm: 8 bayt
- Oraliq: -9,223,372,036,854,775,808 dan 9,223,372,036,854,775,807 gacha
- Ishlatilishi: Bank tranzaksiyalari, katta ID'lar
Misollar:
-- Bank tranzaksiyalari
CREATE TABLE transactions (
transaction_id BIGINT PRIMARY KEY,
account_number BIGINT,
amount BIGINT, -- So'm (1,000,000,000 = 1 mlrd)
transaction_time TIMESTAMP
);
-- Misol: 5 milliard so'm
INSERT INTO transactions VALUES
(1, 1234567890123456, 5000000000, NOW());SMALLINT — kichik butun sonlar uchun (xotira tejash).
Xususiyatlari:
- Hajm: 2 bayt
- Oraliq: -32,768 dan 32,767 gacha
- Ishlatilishi: Yosh, kun, oy
Misol:
CREATE TABLE people (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age SMALLINT, -- 0-120
birth_month SMALLINT -- 1-12
);DECIMAL(precision, scale) — pul va aniq hisob-kitoblar uchun.
Parametrlar:
- precision — umumiy raqamlar soni
- scale — verguldan keyingi raqamlar soni
Misollar:
-- DECIMAL(10, 2) = 12345678.90
-- ↑ ↑
-- 10 2
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10, 2), -- 99,999,999.99 gacha
weight DECIMAL(8, 3), -- 99,999.999 gacha
discount_percent DECIMAL(5, 2) -- 999.99 gacha
);
-- Misollar
INSERT INTO products (name, price, weight, discount_percent) VALUES
('Laptop', 5500000.99, 2.450, 15.50),
('Phone', 3200000.00, 0.185, 10.00),
('Tablet', 1800000.50, 0.500, 5.25);
SELECT
name,
price,
price * (1 - discount_percent / 100) AS discounted_price
FROM products;Natija:
name | price | discounted_price
---------+------------+------------------
Laptop | 5500000.99 | 4647500.84
Phone | 3200000.00 | 2880000.00
Tablet | 1800000.50 | 1705500.47
REAL — taxminiy o'nlik sonlar (4 bayt)
DOUBLE PRECISION — aniqroq o'nlik sonlar (8 bayt)
Ogohlantirish:
CREATE TABLE scientific_data (
id SERIAL PRIMARY KEY,
temperature REAL, -- Harorat
pressure DOUBLE PRECISION, -- Bosim
ph_level REAL -- pH darajasi
);
INSERT INTO scientific_data (temperature, pressure, ph_level) VALUES
(36.6, 101325.5, 7.4),
(38.2, 101280.3, 7.2);SERIAL — avtomatik o'suvchi INTEGER (1, 2, 3, ...)
BIGSERIAL — avtomatik o'suvchi BIGINT
Xususiyatlari:
- Har safar yangi row qo'shilganda avtomatik ortadi
- Ko'pincha PRIMARY KEY sifatida ishlatiladi
- Qo'lda qiymat berish shart emas
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- Avtomatik: 1, 2, 3, ...
username VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW()
);
-- id ni ko'rsatmasdan qo'shamiz
INSERT INTO users (username) VALUES
('ali_dev'),
('madina_code'),
('bekzod_pro');
SELECT * FROM users;Natija:
id | username | created_at
----+-------------+-------------------------
1 | ali_dev | 2026-01-22 17:50:00
2 | madina_code | 2026-01-22 17:50:01
3 | bekzod_pro | 2026-01-22 17:50:02
CHAR(n) — aniq n ta belgili matn. Agar kam bo'lsa, bo'sh joy (space) bilan to'ldiriladi.
CREATE TABLE codes (
id SERIAL PRIMARY KEY,
country_code CHAR(2), -- UZ, US, RU (doim 2 ta)
postal_code CHAR(6) -- 100000 (doim 6 ta)
);
INSERT INTO codes (country_code, postal_code) VALUES
('UZ', '100000'),
('US', '10001 '); -- Bo'sh joy bilan to'ldiriladi
-- 'UZ' → 'UZ' (2 ta belgi)
-- Ichki: 'UZ ' (bo'sh joy bilan 2 ta)Qachon ishlatiladi:
- ✅ Telefon kodi (+998)
- ✅ Davlat kodi (UZ, US, RU)
- ✅ ZIP kod
- ❌ Ism, Familiya (uzunlik har xil)
VARCHAR(n) — maksimal n belgigacha bo'lgan matn. Faqat kerakli joy egallanadi.
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
phone VARCHAR(20)
);
INSERT INTO customers VALUES
(1, 'Ali', 'Valiyev', 'ali@example.uz', '+998901234567'),
(2, 'Madina', 'K', 'madina@example.uz', '+998907777777');
-- 'Ali' → 3 ta belgini egalaydi
-- 'Madina' → 6 ta belgini egalaydiCHAR vs VARCHAR:
| Xususiyat | CHAR(10) | VARCHAR(10) |
|---|---|---|
| 'Ali' saqlanganda | 'Ali ' (10 bayt) | 'Ali' (3 bayt) |
| Tezlik | Biroz tezroq | Biroz sekinroq |
| Xotira | Ko'proq | Kamroq |
| Ishlatish | Aniq uzunlik | O'zgaruvchan |
TEXT — cheksiz uzunlikdagmatn. Izohlr, maqolalar, kontentlar uchun.
CREATE TABLE blog_posts (
id SERIAL PRIMARY KEY,
title VARCHAR(200),
slug VARCHAR(200),
content TEXT, -- Cheksiz
excerpt TEXT,
meta_description TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Katta matnni saqlash
INSERT INTO blog_posts (title, slug, content) VALUES
(
'PostgreSQL Tutorial',
'postgresql-tutorial',
'Bu juda uzun maqola matni... (1000+ qator)'
);Qachon ishlatiladi:
- ✅ Blog maqolalari
- ✅ Izohlar, sharhlar
- ✅ Tavsiflar (description)
- ✅ JSON matnlar
- ❌ Qisqa matnlar (VARCHAR ishlating)
DATE — yil, oy, kun. Vaqt yo'q.
Format: YYYY-MM-DD
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
birth_date DATE,
hire_date DATE,
last_promotion DATE
);
INSERT INTO employees VALUES
(1, 'Ali Valiyev', '2000-05-15', '2024-01-10', '2025-06-01'),
(2, 'Madina Karimova', '1998-12-25', '2023-03-20', NULL);
-- Yoshni hisoblash
SELECT
name,
birth_date,
DATE_PART('year', AGE(birth_date)) AS age
FROM employees;Natija:
name | birth_date | age
-----------------+------------+-----
Ali Valiyev | 2000-05-15 | 25
Madina Karimova | 1998-12-25 | 27
TIME — soat, daqiqa, soniya. Sana yo'q.
Format: HH:MM:SS
CREATE TABLE schedule (
id SERIAL PRIMARY KEY,
course_name VARCHAR(100),
start_time TIME,
end_time TIME
);
INSERT INTO schedule VALUES
(1, 'PostgreSQL Basics', '09:00:00', '11:00:00'),
(2, 'Advanced SQL', '14:30:00', '16:30:00'),
(3, 'Database Design', '17:00:00', '19:00:00');
SELECT
course_name,
start_time,
end_time,
end_time - start_time AS duration
FROM schedule;TIMESTAMP — to'liq sana va vaqt.
Format: YYYY-MM-DD HH:MM:SS
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_name VARCHAR(100),
product_name VARCHAR(100),
order_time TIMESTAMP DEFAULT NOW(),
shipped_time TIMESTAMP,
delivered_time TIMESTAMP
);
INSERT INTO orders (customer_name, product_name) VALUES
('Ali', 'Laptop'),
('Vali', 'Phone');
-- Buyurtma qilingan vaqtni ko'rish
SELECT
id,
customer_name,
product_name,
order_time,
NOW() - order_time AS time_since_order
FROM orders;TIMESTAMPTZ — sana, vaqt + vaqt zonasi (timezone).
Nima uchun kerak?
- Global ilovalar (butun dunyo)
- Turli mamlakatlar
- Server bir joyda, foydalanuvchi boshqa joyda
CREATE TABLE events (
id SERIAL PRIMARY KEY,
event_name VARCHAR(200),
scheduled_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Toshkent vaqti bilan
INSERT INTO events (event_name, scheduled_at) VALUES
('PostgreSQL Conference', '2026-06-15 10:00:00+05:00');
-- Har xil vaqt zonalarida ko'rish
SELECT
event_name,
scheduled_at,
scheduled_at AT TIME ZONE 'Asia/Tashkent' AS tashkent_time,
scheduled_at AT TIME ZONE 'America/New_York' AS newyork_time,
scheduled_at AT TIME ZONE 'Europe/London' AS london_time
FROM events;INTERVAL — vaqt davomi (davomiylik).
Misollar:
3 days— 3 kun2 hours 30 minutes— 2 soat 30 daqiqa1 year 6 months— 1 yil 6 oy
CREATE TABLE subscriptions (
id SERIAL PRIMARY KEY,
user_name VARCHAR(100),
start_date DATE,
duration INTERVAL,
end_date DATE
);
INSERT INTO subscriptions VALUES
(1, 'Ali', '2026-01-01', '1 month', '2026-02-01'),
(2, 'Vali', '2026-01-01', '1 year', '2027-01-01'),
(3, 'Madina', '2026-01-15', '3 months', '2026-04-15');
-- Qolgan vaqtni hisoblash
SELECT
user_name,
end_date,
end_date - CURRENT_DATE AS days_remaining,
CASE
WHEN end_date < CURRENT_DATE THEN 'Expired'
WHEN end_date - CURRENT_DATE <= 7 THEN 'Expiring Soon'
ELSE 'Active'
END AS status
FROM subscriptions;BOOLEAN — TRUE, FALSE, yoki NULL.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100),
is_active BOOLEAN DEFAULT TRUE,
is_verified BOOLEAN DEFAULT FALSE,
is_admin BOOLEAN DEFAULT FALSE,
newsletter_subscribed BOOLEAN DEFAULT TRUE
);
INSERT INTO users (username, email, is_verified) VALUES
('ali_dev', 'ali@example.uz', TRUE),
('vali_code', 'vali@example.uz', FALSE);
-- Faqat faol foydalanuvchilar
SELECT * FROM users WHERE is_active = TRUE;
-- Tasdiqlangan va admin'lar
SELECT * FROM users
WHERE is_verified = TRUE AND is_admin = TRUE;
-- Newsletter'ga obuna bo'lmaganlar
SELECT username, email
FROM users
WHERE newsletter_subscribed = FALSE;ARRAY — bir nechta qiymatlarni bitta ustunda saqlash.
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
phone_numbers TEXT[], -- Telefon raqamlar
hobbies TEXT[], -- Qiziqishlar
grades INTEGER[] -- Baholar
);
INSERT INTO students VALUES
(1, 'Ali',
ARRAY['+998901234567', '+998971234567'],
ARRAY['Programming', 'Reading', 'Football'],
ARRAY[5, 4, 5, 5, 4]
),
(2, 'Madina',
ARRAY['+998907777777'],
ARRAY['Design', 'Photography'],
ARRAY[5, 5, 5, 4, 5]
);
-- Massivdan elementga murojaat
SELECT
name,
phone_numbers[1] AS primary_phone, -- Birinchi telefon
hobbies[1] AS main_hobby, -- Birinchi qiziqish
array_length(grades, 1) AS total_grades
FROM students;UUID — Global noyob ID (128-bit).
Format: a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
-- UUID extension'ni faollashtirish
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE sessions (
session_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
user_id INTEGER,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Avtomatik UUID yaratiladi
INSERT INTO sessions (user_id, ip_address) VALUES
(1, '192.168.1.100'),
(2, '10.0.0.50');
SELECT * FROM sessions;Natija:
session_id | user_id | ip_address | created_at
--------------------------------------+---------+---------------+------------
a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 | 1 | 192.168.1.100 | 2026-01-22...
b1ffdca8-8d0c-5fg9-cc7e-7cc0ce491b22 | 2 | 10.0.0.50 | 2026-01-22...
JSON — JavaScript Object Notation
JSONB — Binary JSON (tezroq, index qo'yish mumkin)
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
specs JSONB, -- Texnik xususiyatlar
metadata JSONB -- Qo'shimcha ma'lumotlar
);
INSERT INTO products (name, specs, metadata) VALUES
('Laptop',
'{"cpu": "Intel i7", "ram": "16GB", "storage": "512GB SSD"}'::jsonb,
'{"color": "silver", "warranty": "2 years"}'::jsonb
),
('Phone',
'{"cpu": "Snapdragon 888", "ram": "8GB", "camera": "108MP"}'::jsonb,
'{"color": "black", "5g": true}'::jsonb
);
-- JSON'dan qiymat olish
SELECT
name,
specs->>'cpu' AS processor,
specs->>'ram' AS memory,
metadata->>'color' AS color
FROM products;
-- JSON ichida qidirish
SELECT name FROM products
WHERE specs->>'ram' = '16GB';Database — ma'lumotlarning umumiy konteyner
i.
Sintaksis:
CREATE DATABASE database_nomi;Misollar:
-- Oddiy database
CREATE DATABASE my_shop;
-- Batafsil (encoding, locale)
CREATE DATABASE my_shop
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8';
-- Database'ga ulanish
\c my_shop
-- Database'ni o'chirish
DROP DATABASE IF EXISTS my_shop;Real proyekt misoli:
-- E-commerce database
CREATE DATABASE ecommerce_db
WITH
ENCODING = 'UTF8';
\c ecommerce_db
-- Blog database
CREATE DATABASE blog_db;
\c blog_db
-- Bank database
CREATE DATABASE bank_system;Table — ma'lumotlarni saqlash uchun struktura.
Sintaksis:
CREATE TABLE table_nomi (
column1 datatype constraints,
column2 datatype constraints,
...
);Oddiy misol:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);To'liq misol (E-commerce):
-- Kategoriyalar jadvali
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
-- Mahsulotlar jadvali
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
description TEXT,
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
stock_quantity INTEGER DEFAULT 0 CHECK (stock_quantity >= 0),
category_id INTEGER REFERENCES categories(id),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Mijozlar jadvali
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
phone VARCHAR(20),
address TEXT,
city VARCHAR(50),
postal_code VARCHAR(10),
registered_at TIMESTAMP DEFAULT NOW()
);
-- Buyurtmalar jadvali
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id),
total_amount DECIMAL(10, 2) NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
ordered_at TIMESTAMP DEFAULT NOW(),
shipped_at TIMESTAMP,
delivered_at TIMESTAMP
);
-- Buyurtma elementlari
CREATE TABLE order_items (
id SERIAL PRIMARY KEY,
order_id INTEGER REFERENCES orders(id),
product_id INTEGER REFERENCES products(id),
quantity INTEGER NOT NULL CHECK (quantity > 0),
unit_price DECIMAL(10, 2) NOT NULL,
subtotal DECIMAL(10, 2) GENERATED ALWAYS AS (quantity * unit_price) STORED
);INSERT — jadvalga yangi ma'lumotlar qo'shish.
Sintaksis:
INSERT INTO table_nomi (column1, column2, ...)
VALUES (value1, value2, ...);Oddiy misollar:
-- Bitta qator qo'shish
INSERT INTO users (username, email)
VALUES ('ali_dev', 'ali@example.uz');
-- Bir nechta qator qo'shish
INSERT INTO users (username, email) VALUES
('madina_code', 'madina@example.uz'),
('bekzod_pro', 'bekzod@example.uz'),
('dinara_dev', 'dinara@example.uz');
-- Barcha ustunlar uchun
INSERT INTO users
VALUES (1, 'test_user', 'test@example.uz', NOW());Real proyekt (E-commerce):
-- 1. Kategoriyalar qo'shish
INSERT INTO categories (name, description) VALUES
('Electronics', 'Electronic devices and accessories'),
('Clothing', 'Men and women clothing'),
('Books', 'Physical and digital books'),
('Home & Garden', 'Home decor and garden tools');
-- 2. Mahsulotlar qo'shish
INSERT INTO products (name, description, price, stock_quantity, category_id) VALUES
('Laptop HP ProBook', '15.6 inch, i5, 8GB RAM', 5500000, 15, 1),
('iPhone 15 Pro', '256GB, Blue Titanium', 12000000, 8, 1),
('T-Shirt Nike', '100% Cotton, Size M', 150000, 50, 2),
('PostgreSQL Book', 'Complete PostgreSQL Guide', 250000, 30, 3);
-- 3. Mijozlar qo'shish
INSERT INTO customers (first_name, last_name, email, phone, city) VALUES
('Ali', 'Valiyev', 'ali@gmail.com', '+998901234567', 'Tashkent'),
('Madina', 'Karimova', 'madina@gmail.com', '+998907654321', 'Samarkand');
-- 4. Buyurtma qo'shish
INSERT INTO orders (customer_id, total_amount, status)
VALUES (1, 5650000, 'processing');
-- 5. Buyurtma elementlarini qo'shish
INSERT INTO order_items (order_id, product_id, quantity, unit_price) VALUES
(1, 1, 1, 5500000), -- 1 ta laptop
(1, 3, 1, 150000); -- 1 ta futbolkaINSERT ... RETURNING:
-- Qo'shilgan qatorni qaytarish
INSERT INTO users (username, email)
VALUES ('new_user', 'new@example.uz')
RETURNING *;
-- Fqat ID'ni qaytarish
INSERT INTO products (name, price, category_id)
VALUES ('New Product', 100000, 1)
RETURNING id, name;SELECT — ma'lumotlarni o'qish (eng ko'p ishlatiladigan buyruq).
Sintaksis:
SELECT column1, column2, ...
FROM table_name
WHERE condition
ORDER BY column
LIMIT number;Oddiy misollar:
-- Barcha ustunlar
SELECT * FROM users;
-- Aniq ustunlar
SELECT username, email FROM users;
-- Shart bilan
SELECT * FROM users WHERE id = 1;
-- Tartiblash
SELECT * FROM users ORDER BY created_at DESC;
-- Cheklash
SELECT * FROM users LIMIT 5;
-- Kombinatsiya
SELECT username, email
FROM users
WHERE created_at > '2026-01-01'
ORDER BY username
LIMIT 10;Murakkab misollar:
-- WHERE bilan
SELECT name, price
FROM products
WHERE price > 1000000 AND stock_quantity > 0;
-- LIKE bilan (qidiruv)
SELECT * FROM products
WHERE name LIKE '%Laptop%';
-- IN bilan
SELECT * FROM products
WHERE category_id IN (1, 2, 3);
-- BETWEEN bilan
SELECT name, price FROM products
WHERE price BETWEEN 500000 AND 2000000;
-- ORDER BY bilan
SELECT name, price FROM products
ORDER BY price DESC, name ASC;
-- LIMIT va OFFSET (pagination)
SELECT * FROM products
ORDER BY id
LIMIT 10 OFFSET 20; -- 3-sahifa (har sahifada 10 ta)Aggregate Functions:
-- Hisoblash
SELECT COUNT(*) AS total_users FROM users;
SELECT COUNT(*) AS total_products FROM products;
-- Summa
SELECT SUM(price) AS total_value FROM products;
-- O'rtacha
SELECT AVG(price) AS average_price FROM products;
-- Minimal va Maksimal
SELECT
MIN(price) AS cheapest,
MAX(price) AS most_expensive
FROM products;
-- Guruhlash
SELECT
category_id,
COUNT(*) AS product_count,
AVG(price) AS avg_price
FROM products
GROUP BY category_id;
-- HAVING (groupdan keyin filter)
SELECT
category_id,
COUNT(*) AS count
FROM products
GROUP BY category_id
HAVING COUNT(*) > 5;JOINlar:
-- INNER JOIN
SELECT
p.name AS product_name,
c.name AS category_name,
p.price
FROM products p
INNER JOIN categories c ON p.category_id = c.id;
-- LEFT JOIN
SELECT
c.name AS category_name,
COUNT(p.id) AS product_count
FROM categories c
LEFT JOIN products p ON c.id = p.category_id
GROUP BY c.id, c.name;
-- Murakkab JOIN
SELECT
o.id AS order_id,
c.first_name || ' ' || c.last_name AS customer_name,
p.name AS product_name,
oi.quantity,
oi.subtotal
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id;UPDATE — mavjud ma'lumotlarni o'zgartirish.
Sintaksis:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;Oddiy misollar:
-- Bitta ustunni yangilash
UPDATE users
SET email = 'new_email@example.uz'
WHERE id = 1;
-- Bir nechta ustun
UPDATE users
SET
username = 'updated_username',
email = 'updated@example.uz'
WHERE id = 2;
-- Barcha qatorlar (ehtiyot bo'ling!)
UPDATE products
SET is_active = FALSE;Real misollar:
-- Narxni 10% oshirish
UPDATE products
SET price = price * 1.10
WHERE category_id = 1;
-- Stock'ni kamaytirish (sotilganda)
UPDATE products
SET stock_quantity = stock_quantity - 1
WHERE id = 5 AND stock_quantity > 0;
-- Status o'zgartirish
UPDATE orders
SET
status = 'shipped',
shipped_at = NOW()
WHERE id = 100;
-- Ommaviy yangilash
UPDATE products
SET
is_active = TRUE,
updated_at = NOW()
WHERE stock_quantity > 0;
-- Subquery bilan
UPDATE products
SET category_id = (SELECT id FROM categories WHERE name = 'Electronics')
WHERE name LIKE '%Phone%';UPDATE ... RETURNING:
-- Yangilangan qatorni qaytarish
UPDATE products
SET price = 1500000
WHERE id = 10
RETURNING *;
-- Faqat kerakli ustunlar
UPDATE users
SET email = 'newemail@example.uz'
WHERE username = 'ali_dev'
RETURNING id, username, email;DELETE — qatorlarni o'chirish.
Sintaksis:
DELETE FROM table_name
WHERE condition;Oddiy misollar:
-- Bitta qatorni o'chirish
DELETE FROM users WHERE id = 5;
-- Shart bilan
DELETE FROM products WHERE stock_quantity = 0;
-- Barcha qatorlar (ehtiyot!)
DELETE FROM temp_table;Real misollar:
-- Eski buyurtmalarni o'chirish
DELETE FROM orders
WHERE ordered_at < '2025-01-01';
-- Nofaol foydalanuvchilar
DELETE FROM users
WHERE is_active = FALSE
AND last_login < NOW() - INTERVAL '1 year';
-- Nolga teng stock
DELETE FROM products
WHERE stock_quantity = 0 AND is_active = FALSE;
-- Subquery bilan
DELETE FROM order_items
WHERE order_id IN (
SELECT id FROM orders
WHERE status = 'cancelled'
);DELETE ... RETURNING:
-- O'chirilgan qatorni qaytarish
DELETE FROM products
WHERE id = 100
RETURNING *;
-- Nechta o'chirilganini ko'rish
DELETE FROM users
WHERE is_active = FALSE
RETURNING id, username;TRUNCATE vs DELETE:
-- DELETE - qator-qatordan o'chiradi (sekin)
DELETE FROM large_table;
-- TRUNCATE - butun jadvalni tozalaydi (tez)
TRUNCATE TABLE large_table;
-- TRUNCATE - cascade bilan
TRUNCATE TABLE orders CASCADE;
-- TRUNCATE - ID resetlash
TRUNCATE TABLE users RESTART IDENTITY;Primary Key — har bir qatorni noyob identifikatsiya qiluvchi kalit.
Xususiyatlari:
- ✅ Har bir qatorda **n
oyob** bo'lishi kerak
- ✅ NULL bo'lmasligi kerak
- ✅ Har bir jadvalda faqat bitta Primary Key
-- Oddiy Primary Key
CREATE TABLE users (
id INTEGER PRIMARY KEY,
username VARCHAR(50)
);
-- SERIAL bilan (tavsiya qilinadi)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50)
);
-- Keyinchalik qo'shish
CREATE TABLE users (
id INTEGER,
username VARCHAR(50)
);
ALTER TABLE users ADD PRIMARY KEY (id);
-- Composite Primary Key (birlashma)
CREATE TABLE enrollments (
student_id INTEGER,
course_id INTEGER,
enrolled_date DATE,
PRIMARY KEY (student_id, course_id)
);Constraints — ma'lumotlarning to'g'riligini ta'minlash uchun qoidalar.
Ma'lumot bo'sh bo'lmasligi kerak.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL, -- Majburiy
price DECIMAL(10,2) NOT NULL, -- Majburiy
description TEXT -- Ixtiyoriy
);
-- Xato
INSERT INTO products (description) VALUES ('Test');
-- ERROR: null value in column "name"
-- To'g'ri
INSERT INTO products (name, price) VALUES ('Product', 100);Qiymat takrorlanmasligi kerak.
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL, -- Takrorlanmas
email VARCHAR(100) UNIQUE NOT NULL, -- Takrorlanmas
phone VARCHAR(20) -- Takrorlanishi mumkin
);
-- Xato
INSERT INTO users (username, email) VALUES ('ali', 'ali@example.uz');
INSERT INTO users (username, email) VALUES ('ali', 'other@example.uz');
-- ERROR: duplicate key value
-- To'g'ri
INSERT INTO users (username, email) VALUES ('vali', 'vali@example.uz');Qiymat ma'lum shartga mos bo'lishi kerak.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2) CHECK (price >= 0), -- Musbat
stock INTEGER CHECK (stock >= 0), -- Musbat yoki 0
discount_percent INTEGER CHECK (discount_percent BETWEEN 0 AND 100)
);
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50),
age INTEGER CHECK (age >= 18 AND age <= 100),
email VARCHAR(100) CHECK (email LIKE '%@%')
);
-- Xato
INSERT INTO products (name, price, stock) VALUES ('Test', -100, 5);
-- ERROR: check constraint violated
-- To'g'ri
INSERT INTO products (name, price, stock) VALUES ('Test', 100, 5);Qiymat berilmasa, standart qiymat qo'yiladi.
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title VARCHAR(200),
content TEXT,
status VARCHAR(20) DEFAULT 'draft',
is_published BOOLEAN DEFAULT FALSE,
view_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- DEFAULT qiymatlar avtomatik qo'yiladi
INSERT INTO posts (title, content)
VALUES ('My First Post', 'Hello World!');
SELECT * FROM posts;
-- status: 'draft', is_published: FALSE, view_count: 0Jadvallarni bog'lash uchun.
-- Kategoriyalar
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
-- Mahsulotlar (category_id → categories.id)
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
category_id INTEGER,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
-- Qisqa yozuv
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
category_id INTEGER REFERENCES categories(id)
);
-- ON DELETE CASCADE - kategoriya o'chirilsa, mahsulotlar ham o'chiriladi
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
category_id INTEGER REFERENCES categories(id) ON DELETE CASCADE
);
-- ON DELETE SET NULL - kategoriya o'chirilsa, NULL qo'yiladi
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
category_id INTEGER REFERENCES categories(id) ON DELETE SET NULL
);CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL
CHECK (length(username) >= 3),
email VARCHAR(100) UNIQUE NOT NULL
CHECK (email LIKE '%@%.%'),
password_hash VARCHAR(255) NOT NULL,
age INTEGER CHECK (age >= 18 AND age <= 120),
is_active BOOLEAN DEFAULT TRUE,
is_verified BOOLEAN DEFAULT FALSE,
role VARCHAR(20) DEFAULT 'user'
CHECK (role IN ('user', 'admin', 'moderator')),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name VARCHAR(100) UNIQUE NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT TRUE
);
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
slug VARCHAR(200) UNIQUE NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL CHECK (price >= 0),
sale_price DECIMAL(10,2) CHECK (sale_price >= 0 AND sale_price < price),
stock_quantity INTEGER DEFAULT 0 CHECK (stock_quantity >= 0),
category_id INTEGER NOT NULL REFERENCES categories(id) ON DELETE RESTRICT,
created_by INTEGER REFERENCES users(id) ON DELETE SET NULL,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);Bu bo'limda siz real e-commerce tizimi uchun to'liq database yaratish va 10 ta topshiriqni bajarish kerak.
Quyidagi jadvallar sizning database'ingizda mavjud. Topshiriqlarni bajarish uchun ushbu ma'lumotlardan foydalaning.
💡 Eslatma: Database yaratish va to'ldirish uchun to'liq SQL skriptni bu yerdan yuklab olishingiz mumkin.
Yuqoridagi skript ishga tushgandan keyin, quyidagi jadvallar yaratiladi va ma'lumotlar bilan to'ldiriladi:
┌────┬───────────────┬──────────────────────────────────────┬───────────┬─────────────────────┐
│ id │ name │ description │ is_active │ created_at │
├────┼───────────────┼──────────────────────────────────────┼───────────┼─────────────────────┤
│ 1 │ Electronics │ Electronic devices and accessories │ TRUE │ 2026-01-22 12:00:00 │
│ 2 │ Clothing │ Men and women clothing │ TRUE │ 2026-01-22 12:00:00 │
│ 3 │ Books │ Physical and digital books │ TRUE │ 2026-01-22 12:00:00 │
│ 4 │ Home & Garden │ Home decor and garden tools │ TRUE │ 2026-01-22 12:00:00 │
│ 5 │ Sports │ Sports equipment and accessories │ TRUE │ 2026-01-22 12:00:00 │
│ 6 │ Beauty │ Cosmetics and personal care │ TRUE │ 2026-01-22 12:00:00 │
│ 7 │ Toys │ Kids toys and games │ TRUE │ 2026-01-22 12:00:00 │
└────┴───────────────┴──────────────────────────────────────┴───────────┴─────────────────────┘
┌────┬───────────────────────┬─────────────────────────┬────────────┬────────────┬────────────────┬─────────────┐
│ id │ name │ slug │ price │ sale_price │ stock_quantity │ category_id │
├────┼───────────────────────┼─────────────────────────┼────────────┼────────────┼────────────────┼─────────────┤
│ 1 │ Laptop HP ProBook 450 │ laptop-hp-probook-450 │ 5500000.00 │ 5200000.00 │ 15 │ 1 │
│ 2 │ iPhone 15 Pro │ iphone-15-pro │12000000.00 │ NULL │ 8 │ 1 │
│ 3 │ Samsung Galaxy S24 │ samsung-galaxy-s24 │ 9500000.00 │ 9000000.00 │ 12 │ 1 │
│ 4 │ AirPods Pro 2 │ airpods-pro-2 │ 2500000.00 │ NULL │ 25 │ 1 │
│ 5 │ iPad Air 5 │ ipad-air-5 │ 6500000.00 │ 6200000.00 │ 10 │ 1 │
│ 6 │ Dell XPS 13 │ dell-xps-13 │ 8500000.00 │ NULL │ 7 │ 1 │
│ 7 │ Sony WH-1000XM5 │ sony-wh-1000xm5 │ 3500000.00 │ 3200000.00 │ 18 │ 1 │
│ 8 │ Apple Watch Series 9 │ apple-watch-series-9 │ 4500000.00 │ NULL │ 15 │ 1 │
│ 9 │ Nike Air Max Shoes │ nike-air-max-shoes │ 850000.00 │ 750000.00 │ 50 │ 2 │
│ 10 │ Adidas T-Shirt │ adidas-t-shirt │ 150000.00 │ NULL │ 100 │ 2 │
└────┴───────────────────────┴─────────────────────────┴────────────┴────────────┴────────────────┴─────────────┘
┌────┬────────────┬───────────┬─────────────────────────┬──────────────────┬──────────────────────┬───────────┬─────────────┐
│ id │ first_name │ last_name │ email │ phone │ address │ city │ postal_code │
├────┼────────────┼───────────┼─────────────────────────┼──────────────────┼──────────────────────┼───────────┼─────────────┤
│ 1 │ Ali │ Valiyev │ ali.valiyev@gmail.com │ +998901234567 │ Chilonzor 12-9-45 │ Tashkent │ 100115 │
│ 2 │ Madina │ Karimova │ madina.k@gmail.com │ +998907654321 │ Mirzo Ulugbek 5-4-87 │ Tashkent │ 100125 │
│ 3 │ Bekzod │ Tursunov │ bekzod.t@gmail.com │ +998909876543 │ Registon 15 │ Samarkand │ 140100 │
│ 4 │ Dilnoza │ Rahimova │ dilnoza.r@gmail.com │ +998941234567 │ Navoi 88 │ Bukhara │ 200100 │
│ 5 │ Jamshid │ Aliyev │ jamshid.a@gmail.com │ +998977777777 │ Yunusobod 10-12-5 │ Tashkent │ 100093 │
│ 6 │ Zarina │ Hasanova │ zarina.h@gmail.com │ +998935555555 │ Amir Temur 25 │ Samarkand │ 140200 │
│ 7 │ Sardor │ Mahmudov │ sardor.m@gmail.com │ +998998888888 │ Mustaqillik 55 │ Fergana │ 150100 │
│ 8 │ Nilufar │ Yusupova │ nilufar.y@gmail.com │ +998906666666 │ Oybek 12 │ Tashkent │ 100000 │
└────┴────────────┴───────────┴─────────────────────────┴──────────────────┴──────────────────────┴───────────┴─────────────┘
┌────┬─────────────┬────────────────┬──────────────┬─────────────────┬──────────────┬────────────┬────────────────┐
│ id │ customer_id │ order_number │ total_amount │ discount_amount │ final_amount │ status │ payment_method │
├────┼─────────────┼────────────────┼──────────────┼─────────────────┼──────────────┼────────────┼────────────────┤
│ 1 │ 1 │ ORD-2025-0001 │ 5700000.00 │ 100000.00 │ 5600000.00 │ delivered │ cash │
│ 2 │ 1 │ ORD-2025-0002 │ 450000.00 │ 50000.00 │ 400000.00 │ delivered │ card │
│ 3 │ 2 │ ORD-2025-0003 │12000000.00 │ 0.00 │12000000.00 │ delivered │ card │
│ 4 │ 3 │ ORD-2025-0004 │ 1050000.00 │ 0.00 │ 1050000.00 │ delivered │ cash │
│ 5 │ 4 │ ORD-2025-0005 │ 850000.00 │ 100000.00 │ 750000.00 │ shipped │ card │
│ 6 │ 5 │ ORD-2025-0006 │ 3850000.00 │ 0.00 │ 3850000.00 │ processing │ card │
│ 7 │ 6 │ ORD-2025-0007 │ 650000.00 │ 50000.00 │ 600000.00 │ pending │ cash │
│ 8 │ 7 │ ORD-2025-0008 │ 2950000.00 │ 200000.00 │ 2750000.00 │ delivered │ card │
│ 9 │ 8 │ ORD-2025-0009 │ 1200000.00 │ 0.00 │ 1200000.00 │ cancelled │ cash │
│ 10 │ 9 │ ORD-2025-0010 │ 850000.00 │ 0.00 │ 850000.00 │ delivered │ card │
└────┴─────────────┴────────────────┴──────────────┴─────────────────┴──────────────┴────────────┴────────────────┘
┌────┬──────────┬────────────┬───────────────────────┬──────────┬────────────┬────────────┐
│ id │ order_id │ product_id │ product_name │ quantity │ unit_price │ subtotal │
├────┼──────────┼────────────┼───────────────────────┼──────────┼────────────┼────────────┤
│ 1 │ 1 │ 1 │ Laptop HP ProBook 450 │ 1 │ 5200000.00 │ 5200000.00 │
│ 2 │ 1 │ 10 │ Adidas T-Shirt │ 2 │ 150000.00 │ 300000.00 │
│ 3 │ 1 │ 25 │ Facial Cleanser │ 2 │ 85000.00 │ 170000.00 │
│ 4 │ 2 │ 11 │ Levi's Jeans 501 │ 1 │ 400000.00 │ 400000.00 │
│ 5 │ 3 │ 2 │ iPhone 15 Pro │ 1 │12000000.00 │12000000.00 │
│ 6 │ 4 │ 9 │ Nike Air Max Shoes │ 1 │ 750000.00 │ 750000.00 │
│ 7 │ 4 │ 13 │ H&M Hoodie │ 1 │ 250000.00 │ 250000.00 │
│ 8 │ 5 │ 9 │ Nike Air Max Shoes │ 1 │ 750000.00 │ 750000.00 │
│ 9 │ 6 │ 4 │ AirPods Pro 2 │ 1 │ 2500000.00 │ 2500000.00 │
│ 10 │ 7 │ 8 │ Apple Watch Series 9 │ 1 │ 4500000.00 │ 4500000.00 │
└────┴──────────┴────────────┴───────────────────────┴──────────┴────────────┴────────────┘
┌────┬────────────┬─────────────┬────────┬─────────────────────────────┬─────────────┐
│ id │ product_id │ customer_id │ rating │ title │ is_verified │
├────┼────────────┼─────────────┼────────┼─────────────────────────────┼─────────────┤
│ 1 │ 1 │ 1 │ 5 │ Ajoyib laptop! │ TRUE │
│ 2 │ 2 │ 2 │ 5 │ Eng yaxshi telefon │ TRUE │
│ 3 │ 9 │ 3 │ 4 │ Yaxshi poyabzal │ TRUE │
│ 4 │ 11 │ 4 │ 5 │ Sifatli jinsi │ TRUE │
│ 5 │ 9 │ 9 │ 3 │ O'rtacha │ TRUE │
│ 6 │ 3 │ 8 │ 5 │ Samsung eng yaxshisi! │ TRUE │
│ 7 │ 15 │ 8 │ 5 │ Python uchun eng yaxshi... │ TRUE │
│ 8 │ 6 │ 12 │ 4 │ Yaxshi laptop │ TRUE │
└────┴────────────┴─────────────┴────────┴─────────────────────────────┴─────────────┘
💡 Eslatma: Yuqoridagi jadvallar sizning database'ingizda qanday ma'lumotlar saqlanayotganini ko'rsatadi. Endi quyidagi topshiriqlarni bajaring!
Yuqoridagi database'ni yaratib, quyidagi topshiriqlarni bajaring:
| # | Qiyinlik | Mavzu | Topshiriq Tavsifi |
|---|---|---|---|
| 1 | 🟢 Oson | SELECT asoslari | Barcha kategoriyalarni, faol mahsulotlarni va Toshkentdagi mijozlarni ko'rsating |
| 2 | 🟢 Oson | WHERE operatorlari | Narxi 1,000,000 so'mdan kam mahsulotlar, stock'i 20 dan kam mahsulotlar, gmail foydalanuvchilarini toping |
| 3 | 🟡 O'rta | ORDER BY & LIMIT | Eng qimmat 5 ta mahsulot, eng yangi 10 mijoz, alfabetik tartiblangan mahsulotlar |
| 4 | 🟡 O'rta | Aggregate Functions | Jami mahsulotlar soni, o'rtacha narx, min/max narx, Electronics kategoriyasi mahsulotlari |
| 5 | 🟡 O'rta | UPDATE | Nike poyabzal narxini 10% oshiring, pending → processing, stock=0 → inactive |
| 6 | 🟡 O'rta | DELETE | Cancelled buyurtmalarni o'chiring, 2024-yilda ro'yxatdan o'tgan nofaol mijozlarni o'chiring |
| 7 | 🔴 Qiyin | GROUP BY & HAVING | Har kategoriyada mahsulot soni, har mijozning buyurtmalari, 2+ buyurtma bergan mijozlar |
| 8 | 🔴 Qiyin | JOIN | Buyurtma mahsulotlari, mahsulot sotilishi statistikasi, to'liq buyurtma ma'lumoti |
| 9 | 🔴 Qiyin | Murakkab so'rovlar | Top 5 daromadli mahsulot, shahar bo'yicha buyurtmalar, 4+ rating'li mahsulotlar |
| 10 | 🟣 Juda Qiyin | Business Analytics | Dekabr oyi daromadi, eng yaxshi mijoz, kategoriya foizlari (CTE ishlatish) |
Topshiriq 1: Oddiy SELECT (Oson)
- Barcha kategoriyalarni ko'rsating
- Barcha faol mahsulotlarni (is_active = TRUE) chiqaring
- Toshkentdagi barcha mijozlarni toping
📖 Yechim
-- 1. Barcha kategoriyalar
SELECT * FROM categories;
-- 2. Faol mahsulotlar
SELECT name, price, stock_quantity
FROM products
WHERE is_active = TRUE;
-- 3. Toshkentdagi mijozlar
SELECT first_name, last_name, email, address
FROM customers
WHERE city = 'Tashkent';- Narxi 1,000,000 so'mdan kam mahsulotlarni toping
- Stock'i 20 dan kam bo'lgan mahsulotlarni ko'rsating
- Email'ida "gmail" bo'lgan mijozlarni toping
📖 Yechim
-- 1. Arzon mahsulotlar
SELECT name, price FROM products
WHERE price < 1000000
ORDER BY price;
-- 2. Kam stock
SELECT name, stock_quantity FROM products
WHERE stock_quantity < 20
ORDER BY stock_quantity;
-- 3. Gmail foydalanuvchilari
SELECT first_name, last_name, email
FROM customers
WHERE email LIKE '%gmail%';- Eng qimmat 5 ta mahsulotni toping
- Eng yangi 10 ta mijozni ko'rsating
- Alfabetik tartibda barcha mahsulotlar nomini chiqaring
📖 Yechim
-- 1. Eng qimmat mahsulotlar
SELECT name, price FROM products
ORDER BY price DESC
LIMIT 5;
-- 2. Eng yangi mijozlar
SELECT first_name, last_name, registered_at
FROM customers
ORDER BY registered_at DESC
LIMIT 10;
-- 3. Alfabetik tartib
SELECT name, category_id, price
FROM products
ORDER BY name ASC;- Jami qancha mahsulot bor?
- Barcha mahsulotlarning o'rtacha narxi qancha?
- Eng arzon va eng qimmat mahsulot narxini toping
- "Electronics" kategoriyasidagi mahsulotlar soni
📖 Yechim
-- 1. Jami mahsulotlar
SELECT COUNT(*) AS total_products FROM products;
-- 2. O'rtacha narx
SELECT
AVG(price) AS average_price,
MIN(price) AS cheapest,
MAX(price) AS most_expensive
FROM products;
-- 3. Eng arzon va qimmat
SELECT
MIN(price) AS min_price,
MAX(price) AS max_price
FROM products;
-- 4. Electronics mahsulotlari
SELECT COUNT(*) AS electronics_count
FROM products
WHERE category_id = 1;- "Nike Air Max Shoes" mahsulotining narxini 10% oshiring
- Barcha "pending" buyurtmalarni "processing" ga o'zgartiring
- Stock'i 0 bo'lgan mahsulotlarni is_active = FALSE qiling
📖 Yechim
-- 1. Narxni oshirish
UPDATE products
SET price = price * 1.10
WHERE name = 'Nike Air Max Shoes'
RETURNING name, price;
-- 2. Status o'zgartirish
UPDATE orders
SET status = 'processing'
WHERE status = 'pending'
RETURNING order_number, status;
-- 3. Stock 0 bo'lganlarni nofaol qilish
UPDATE products
SET is_active = FALSE
WHERE stock_quantity = 0
RETURNING name, stock_quantity, is_active;- Barcha "cancelled" buyurtmalarni o'chiring
- 2024-yilda ro'yxatdan o'tgan va hech qanday buyurtma bermagan mijozlarni o'chiring (EHTIYOTKORLIK bilan!)
📖 Yechim
-- 1. Cancelled buyurtmalar
DELETE FROM orders
WHERE status = 'cancelled'
RETURNING order_number, customer_id;
-- 2. Nofaol mijozlar (ehtiyotkorlik!)
-- Avval tekshiramiz
SELECT c.id, c.first_name, c.last_name, c.registered_at
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE c.registered_at < '2025-01-01'
AND o.id IS NULL;
-- Keyin o'chiramiz (agar rost kerak bo'lsa)
-- DELETE FROM customers
-- WHERE id IN (
-- SELECT c.id FROM customers c
-- LEFT JOIN orders o ON c.id = o.customer_id
-- WHERE c.registered_at < '2025-01-01'
-- AND o.id IS NULL
-- );- Har bir kategoriyada qancha mahsulot bor?
- Har bir mijozning jami buyurtmalari soni
- Faqat 2 tadan ko'p buyurtma bergan mijozlarni ko'rsating
📖 Yechim
-- 1. Kategoriya bo'yicha mahsulotlar
SELECT
c.name AS category_name,
COUNT(p.id) AS product_count,
AVG(p.price) AS avg_price
FROM categories c
LEFT JOIN products p ON c.id = p.category_id
GROUP BY c.id, c.name
ORDER BY product_count DESC;
-- 2. Mijoz bo'yicha buyurtmalar
SELECT
c.first_name || ' ' || c.last_name AS customer_name,
COUNT(o.id) AS total_orders,
SUM(o.final_amount) AS total_spent
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.first_name, c.last_name
ORDER BY total_orders DESC;
-- 3. 2 tadan ko'p buyurtma berganlar
SELECT
c.first_name || ' ' || c.last_name AS customer_name,
COUNT(o.id) AS order_count
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.first_name, c.last_name
HAVING COUNT(o.id) > 2
ORDER BY order_count DESC;- Har bir buyurtmada qaysi mahsulotlar bor?
- Har bir mahsulot qaysi buyurtmalarda sotilgan?
- Mijoz nomi, buyurtma raqami va jami summa
📖 Yechim
-- 1. Buyurtma mahsulotlari
SELECT
o.order_number,
c.first_name || ' ' || c.last_name AS customer,
oi.product_name,
oi.quantity,
oi.unit_price,
oi.subtotal
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN order_items oi ON o.id = oi.order_id
ORDER BY o.ordered_at DESC;
-- 2. Mahsulot sotilishi
SELECT
p.name AS product_name,
COUNT(oi.id) AS times_sold,
SUM(oi.quantity) AS total_quantity,
SUM(oi.subtotal) AS total_revenue
FROM products p
LEFT JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name
ORDER BY total_revenue DESC;
-- 3. To'liq buyurtma ma'lumoti
SELECT
c.first_name || ' ' || c.last_name AS customer_name,
c.email,
o.order_number,
o.status,
o.final_amount,
o.ordered_at
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.ordered_at DESC;- Eng ko'p daromad keltiradigan 5 ta mahsulot
- Har bir shahardan qancha buyurtma berilgan?
- O'rtacha bahosi 4 dan yuqori bo'lgan mahsulotlar
📖 Yechim
-- 1. Top 5 daromadli mahsulotlar
SELECT
p.name,
p.category_id,
SUM(oi.quantity) AS total_sold,
SUM(oi.subtotal) AS total_revenue
FROM products p
JOIN order_items oi ON p.id = oi.product_id
GROUP BY p.id, p.name, p.category_id
ORDER BY total_revenue DESC
LIMIT 5;
-- 2. Shahar bo'yicha buyurtmalar
SELECT
c.city,
COUNT(o.id) AS total_orders,
SUM(o.final_amount) AS total_amount
FROM customers c
JOIN orders o ON c.id = o.customer_id
GROUP BY c.city
ORDER BY total_orders DESC;
-- 3. Yaxshi baholangan mahsulotlar
SELECT
p.name,
AVG(r.rating) AS avg_rating,
COUNT(r.id) AS review_count
FROM products p
JOIN reviews r ON p.id = r.product_id
GROUP BY p.id, p.name
HAVING AVG(r.rating) > 4
ORDER BY avg_rating DESC, review_count DESC;- 2025-yil dekabr oyida qancha daromad bo'lgan?
- Eng yaxshi mijozni toping (eng ko'p pul sarflagan)
- Har bir kategoriyaning foizini hisoblang (jami sotuvdan)
📖 Yechim
-- 1. Dekabr oyi daromadi
SELECT
DATE_TRUNC('month', ordered_at) AS month,
COUNT(id) AS total_orders,
SUM(final_amount) AS total_revenue,
AVG(final_amount) AS avg_order_value
FROM orders
WHERE ordered_at BETWEEN '2025-12-01' AND '2025-12-31'
AND status != 'cancelled'
GROUP BY DATE_TRUNC('month', ordered_at);
-- 2. Eng yaxshi mijoz
SELECT
c.first_name || ' ' || c.last_name AS customer_name,
c.email,
c.city,
COUNT(o.id) AS total_orders,
SUM(o.final_amount) AS total_spent,
AVG(o.final_amount) AS avg_order_value
FROM customers c
JOIN orders o ON c.id = o.customer_id
WHERE o.status != 'cancelled'
GROUP BY c.id, c.first_name, c.last_name, c.email, c.city
ORDER BY total_spent DESC
LIMIT 1;
-- 3. Kategoriya bo'yicha foiz
WITH category_sales AS (
SELECT
c.name AS category_name,
SUM(oi.subtotal) AS category_total
FROM categories c
JOIN products p ON c.id = p.category_id
JOIN order_items oi ON p.id = oi.product_id
JOIN orders o ON oi.order_id = o.id
WHERE o.status != 'cancelled'
GROUP BY c.id, c.name
),
total_sales AS (
SELECT SUM(final_amount) AS grand_total
FROM orders
WHERE status != 'cancelled'
)
SELECT
cs.category_name,
cs.category_total,
ts.grand_total,
ROUND((cs.category_total / ts.grand_total * 100), 2) AS percentage
FROM category_sales cs
CROSS JOIN total_sales ts
ORDER BY percentage DESC;GE
Agar barcha topshiriqlarni bajardingiz bo'lsangiz:
- Inbox/Outbox Pattern:
product_historyjadvali yaratib, har bir mahsulot narxi o'zgarganda tarixni saqlang - Trigger: Mahsulot sotilganda avtomatik
stock_quantityni kamaytiradigan trigger yozing - View: Eng ko'p sotiladigan mahsulotlar uchun view yarating
- Index: Tez-tez qidirilgan ustunlarga index qo'ying
Topshiriqlarni bajarganingizdan so'ng:
- ✅ Har bir so'rovni o'zingizcha yozib ko'ring
- ✅ Natijalarni taqqoslang
- ✅ Tushunmagan joylarni qayta o'rganing
- ✅ O'z loyihangizni boshlang!
- Database, Table, Column, Row tushunchalari
- PostgreSQL'ning barcha asosiy ma'lumot turlari
- CREATE DATABASE va CREATE TABLE
- INSERT, SELECT, UPDATE, DELETE
- Primary Key va barcha Constraints
- Real proyekt misollari
03-DARS: Ma'lumotlarni Qidirish va Filterlash
- WHERE clause (murakkab shartlar)
- LIKE, IN, BETWEEN operatorlari
- ORDER BY (tartibga solish)
- LIMIT va OFFSET (pagination)
- Aggregate Functions (COUNT, SUM, AVG)
- GROUP BY va HAVING
-- Barcha database'lar
\l
-- Barcha jadvallar
\dt
-- Jadval strukturasi
\d table_name
-- Barcha constraint'lar
\d+ table_name
-- SQL yordam
\h CREATE TABLE
-- Psql yordam
\?
-- Vaqt o'lchash
\timing
-- Chiqish
\qHar kuni:
- Kamida bitta yangi jadval yarating
- CRUD operatsiyalarini mashq qiling
- Turli constraint'larni sinab ko'ring
- Real proyekt ustida ishlang
Siz PostgreSQL'ning asosiy SQL buyruqlari va ma'lumot turlarini o'rgandingiz!
Keyingi qadam: 03-DARS: Ma'lumotlarni Qidirish va Filterlash →
💡 Eslatma: Eng yaxshi o'rganish usuli - amaliyot! Har bir misol ustida ishlang va o'zingizning proyektingizni yarating! 🚀