Практика по JOIN

This commit is contained in:
mnoskov
2026-03-08 18:21:19 +03:00
parent 936be276bb
commit 221ca37da6
5 changed files with 188 additions and 0 deletions
@@ -0,0 +1,59 @@
-- Задание 1
SELECT
id,
name,
country,
created_at,
email
FROM mnoskov.users
ORDER BY created_at DESC, name;
-- выбрал эти столбцы потому что так сказано в задании, я бы добавил ещё is_active
-- такая сортировка для того, чтобы даты шли от новых к старым и имена людей за одну дату шли по алфавиту
-- Задание 2
SELECT
id,
name,
country
FROM mnoskov.users
WHERE country = 'US'
ORDER BY name;
SELECT
id,
name,
country
FROM mnoskov.users
WHERE country = 'UK'
ORDER BY name;
-- для маркетолого полезнее первый запрос т.к. там больше данных
-- Задание 3
SELECT
id,
name,
email
FROM mnoskov.users
WHERE email IS NOT NULL
ORDER BY name;
SELECT DISTINCT
lower(email) AS email_lower
FROM mnoskov.users
WHERE email IS NOT NULL;
-- приводить email к одному регистру мб для красоты, вроде везде email принимается и в нижем и в верхнем регистре
-- дубликаты убираем чтобы вытрина занимала меньше места, и чтобы не было повторных рассылок
-- Задание 4
SELECT
id,
name,
created_at
FROM mnoskov.users
WHERE created_at > '2024-02-20 23:59'
ORDER BY created_at DESC
LIMIT 2 OFFSET 1;
-- OFFSET может пригодиться, чтобы взять интервал данных
@@ -0,0 +1,47 @@
-- ПРАКТИКА DDL
-- Задание 1
DROP TABLE IF EXISTS mnoskov.users;
CREATE TABLE mnoskov.users (
id bigint PRIMARY KEY,
name varchar(100) NOT NULL,
age SMALLINT,
email varchar(100),
country char(2), -- прогуглил что распространено сохранять iso-код а не все название
is_active boolean,
created_at timestamptz NOT NULL -- думаю timestamptz, если не учитывать часовой пояс, то даты могут отображаться неверно
);
-- Задание 2
DROP TABLE IF EXISTS mnoskov.products;
CREATE TABLE mnoskov.products (
id bigint PRIMARY KEY,
name varchar(100) NOT NULL,
category varchar(50),
price decimal(10,2) NOT NULL,
in_stock boolean
);
-- Задание 3
DROP TABLE IF EXISTS mnoskov.orders;
CREATE TABLE mnoskov.orders (
id bigint PRIMARY KEY,
user_id bigint,
order_date date NOT NULL, -- в названии date, и тип думаю date
status varchar(20), -- думал лучше int, но судя по заданию DML лучше varchar
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Задание 4
DROP TABLE IF EXISTS mnoskov.order_items;
CREATE TABLE mnoskov.order_items (
order_id bigint,
product_id bigint,
quantity int, -- думал надо smallint но потом подумал что вдруг 50к гвоздей
price_at_purchase decimal(10,2),
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
@@ -0,0 +1,50 @@
-- Задание 1
INSERT INTO mnoskov.users (id, name, age, email, country, is_active, created_at)
VALUES
(1, 'Alice', 25, 'alice@example.com', 'US', true, '2024-01-10 10:00:00'),
(2, 'Bob', 30, 'bob@example.com', 'UK', true, '2024-02-05 09:30:00'),
(3, 'Carol', 27, 'carol@example.com', 'US', false, '2024-03-01 15:20:00'),
(4, 'Diana', 22, 'diana@GMAIL.com', 'US', true, '2024-01-12 08:15:00'),
(5, 'Evan', 35, 'EVAN@example.com', 'UK', true, '2024-01-18 19:40:00'),
(6, 'Farida', 29, 'farida@example.com', 'KZ', true, '2024-02-20 11:05:00'),
(7, 'George', 31, 'george+test@example.com', 'US', true, '2024-03-05 16:45:00'),
(8, 'Helen', 24, NULL, 'UK', false, '2024-03-06 08:20:00'),
(9, 'Ivan', 26, 'ivan@example.com', 'RU', true, '2024-01-11 14:30:00'),
(10, 'Julia', 28, 'julia@example.com', 'US', true, '2024-03-07 18:05:00');
-- Задание 2
INSERT INTO mnoskov.products (id, name, category, price, in_stock)
VALUES
(1, 'iPhone 15', 'Электроника', 80000, true),
(2, 'Kindle', 'Электроника', 15000, true),
(3, 'Кроссовки Nike', 'Одежда', 9000, true),
(4, 'Кроссовки NoName', 'Одежда', 3000, false),
(5, 'Наушники Pro', 'Электроника', 12000, true),
(6, 'Фитнес-браслет', 'Гаджеты', 6000, true),
(7, 'Подарочная карта', 'Сервисы', 1000, true);
-- Задание 3
INSERT INTO mnoskov.orders (id, user_id, order_date, status)
VALUES
(1, 1, '2025-01-10 12:00:00', 'paid'),
(2, 3, '2025-01-12 09:30:00', 'cancelled'),
(3, 1, '2025-01-15 18:20:00', 'paid'),
(4, 2, '2025-01-20 11:05:00', 'created'),
(5, 4, '2025-02-01 17:45:00', 'paid'),
(6, 5, '2025-02-10 10:10:00', 'refunded'),
(7, 7, '2025-03-01 09:00:00', 'paid'),
(8, 9, '2025-03-05 19:30:00', 'paid');
-- Задание 4
INSERT INTO mnoskov.order_items (order_id, product_id, quantity, price_at_purchase)
VALUES
(1, 1, 1, 78000),
(1, 3, 2, 8500),
(2, 2, 1, 14000),
(3, 5, 1, 11000),
(3, 7, 1, 1000),
(4, 2, 1, 15000),
(5, 6, 1, 6000),
(6, 1, 1, 82000),
(7, 3, 1, 9000),
(8, 4, 2, 2800);
@@ -0,0 +1,78 @@
-- Задание 1
SELECT
name,
category,
price,
price * 1.30 AS price_with_markup,
price * 1.50 AS price_with_vat
FROM
mnoskov.products
WHERE
in_stock = TRUE AND
category != 'smartwatch' AND -- категории smartwatch нет в предоставленных данных для заполнения
price BETWEEN 100 AND 1300;
-- Что лучше читается BETWEEN 100 AND 1300 или price >= 100 AND price <= 1300 и почему?
-- Лучше читается первый вариант, потому что просто прочитал и понял, а не думаешь над знаками, и первый вариант короче
-- Задание 2
SELECT
name,
price,
price * 0.85 AS price_with_discount
FROM
mnoskov.products
WHERE
(price < 100 OR price > 1000);
-- Нужно отделять OR скобками, потому что если в условии будет ещё и AND, то логика может поломаться потому что AND выполняется раньше чем OR
-- Задание 3
SELECT
id,
name,
category,
price
FROM
mnoskov.products
WHERE
category IN ('tablet', 'smartphone', 'mouse') AND
price >= 100
ORDER BY
price DESC;
--Задание 4
SELECT
name,
category,
price
FROM
mnoskov.products
WHERE
name NOT LIKE '%iPhone%';
-- Задание 5
-- 1)
SELECT
name,
category,
price
FROM
mnoskov.products
WHERE
name ILIKE '%pro%';
-- 2)
SELECT
name,
category,
price
FROM
mnoskov.products
WHERE
name ILIKE '%mx%'
ORDER BY
price DESC;
-- Для поисковой строи лучше ILIKE, потому что он не учитывает регистр - кто-то пишет с большой буквы, кто-то с маленькой, а кто-то случайно включил капс.