From 240ccccba3e11e8175157310d2b54232d7643c2f Mon Sep 17 00:00:00 2001 From: mnoskov Date: Sun, 15 Mar 2026 21:56:20 +0300 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=D0=BC=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86,=20JOIN,=20UNION,?= =?UTF-8?q?=20=D0=90=D0=B3=D1=80=D0=B5=D1=86=D0=B8=D0=B8=20=D0=B8=20=D0=B3?= =?UTF-8?q?=D1=80=D1=83=D0=BF=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8,?= =?UTF-8?q?=20=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8,=20CTE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DDL_create_first_tables.sql | 4 +--- .../postgresql/2. JOIN/DQL_join_practice.sql | 4 ++-- .../postgresql/3. UNION/DQL_union_practice.sql | 2 +- .../DQL_aggregations&groupings_practice.sql | 4 ++-- .../DQL_functions_practice.sql | 4 ++-- .../6. Подзапросы и CTE/DQL_cte_practice.sql | 18 +++++++++--------- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mnoskov/postgresql/1. Основы/1. Создание_и_изменение_таблиц_и_данных/DDL_create_first_tables.sql b/mnoskov/postgresql/1. Основы/1. Создание_и_изменение_таблиц_и_данных/DDL_create_first_tables.sql index db89114..676ee2f 100644 --- a/mnoskov/postgresql/1. Основы/1. Создание_и_изменение_таблиц_и_данных/DDL_create_first_tables.sql +++ b/mnoskov/postgresql/1. Основы/1. Создание_и_изменение_таблиц_и_данных/DDL_create_first_tables.sql @@ -28,12 +28,10 @@ DROP TABLE IF EXISTS mnoskov.orders; CREATE TABLE mnoskov.orders ( id bigint PRIMARY KEY, user_id bigint, - order_date date NOT NULL, -- в названии date, и тип думаю date + order_date timestamptz NOT NULL, -- в названии date, и тип думаю date status varchar(20), -- думал лучше int, но судя по заданию DML лучше varchar FOREIGN KEY (user_id) REFERENCES users(id) ); -ALTER TABLE mnoskov.orders -ALTER COLUMN order_date TYPE timestamptz; -- Задание 4 diff --git a/mnoskov/postgresql/2. JOIN/DQL_join_practice.sql b/mnoskov/postgresql/2. JOIN/DQL_join_practice.sql index 8ba0e40..639da44 100644 --- a/mnoskov/postgresql/2. JOIN/DQL_join_practice.sql +++ b/mnoskov/postgresql/2. JOIN/DQL_join_practice.sql @@ -16,7 +16,7 @@ LEFT JOIN -- Задание 2 SELECT oi.order_id, - p.name AS prouct_name, + p.name AS product_name, oi.quantity, oi.price_at_purchase FROM @@ -75,7 +75,7 @@ WHERE -- Задание 6 SELECT oi.order_id, - u.id AS user_name, + u.id AS user_id, p.name AS product_name, oi.quantity FROM diff --git a/mnoskov/postgresql/3. UNION/DQL_union_practice.sql b/mnoskov/postgresql/3. UNION/DQL_union_practice.sql index 7ff2b1c..b284f5e 100644 --- a/mnoskov/postgresql/3. UNION/DQL_union_practice.sql +++ b/mnoskov/postgresql/3. UNION/DQL_union_practice.sql @@ -70,6 +70,6 @@ FROM mnoskov.products p LEFT JOIN mnoskov.order_items oi ON p.id = oi.product_id -WHERE oi.product_id = NULL; +WHERE oi.product_id is NULL; -- Проверка IS NULL по полю из order_items, потому что это права таблица, и null будут добавляться в неё -- 1) Понизить цену товара 2) лучше прорекламировать 3) снять с продажи \ No newline at end of file diff --git a/mnoskov/postgresql/4. Агрегации и группировки/DQL_aggregations&groupings_practice.sql b/mnoskov/postgresql/4. Агрегации и группировки/DQL_aggregations&groupings_practice.sql index 28ee152..1058267 100644 --- a/mnoskov/postgresql/4. Агрегации и группировки/DQL_aggregations&groupings_practice.sql +++ b/mnoskov/postgresql/4. Агрегации и группировки/DQL_aggregations&groupings_practice.sql @@ -93,7 +93,7 @@ HAVING count(*) >= 2 ORDER BY active_user_count DESC; --- is_active = true логичнее писать в HAVING, потому что is_active - не агрегат +-- is_active = true логичнее писать в WHERE, потому что is_active - не агрегат -- Если нет страны где больше двух активных юзеров, то ничего не выведется @@ -126,5 +126,5 @@ HAVING sum(quantity * price_at_purchase) < 10000 ORDER BY order_revenue; --- Не понял вопрос: Какие реальные причины могут быть у очень маленьких заказов (1–2 гипотезы)? +-- Не понял вопрос: Какие реальные причины могут быть у очень маленьких заказов (1–2 гипотезы)? Ответ: «доставка пробников/тестовой партии», «использование купонов/бонусов», «технический тест витрины» -- Проще увидеть глазами отфильтрованные микро-заказы \ No newline at end of file diff --git a/mnoskov/postgresql/5. Функции: даты, строки, логика/DQL_functions_practice.sql b/mnoskov/postgresql/5. Функции: даты, строки, логика/DQL_functions_practice.sql index f37e1ef..30d30fb 100644 --- a/mnoskov/postgresql/5. Функции: даты, строки, логика/DQL_functions_practice.sql +++ b/mnoskov/postgresql/5. Функции: даты, строки, логика/DQL_functions_practice.sql @@ -40,7 +40,7 @@ FROM mnoskov.users ORDER BY age; --- Почему удобнее держать логику сегментации в SQL (CASE), а не только в коде приложения? Я не понял этот вопрос. +-- Почему удобнее держать логику сегментации в SQL (CASE), а не только в коде приложения? В каком коде? Если в 'коде приложения' - это какая-то отдельная программа, то могут предположить, чтобы передавать в приложение уже отфильтрованные данные, чтобы задачи базы данных не выносить из базы. -- Если забыть в ветку ELSE, то будет NULL у тех кто никуда не попал @@ -50,7 +50,7 @@ SELECT created_at::date, current_date - created_at::date AS days_since_registration, CASE - WHEN created_at >= current_date - INTERVAL '30 days' THEN 'hot' ELSE 'regular' + WHEN created_at >= current_date - INTERVAL '30 days' THEN 'hot' ELSE NULL END AS hot_flag FROM mnoskov.users diff --git a/mnoskov/postgresql/6. Подзапросы и CTE/DQL_cte_practice.sql b/mnoskov/postgresql/6. Подзапросы и CTE/DQL_cte_practice.sql index 3682f94..cb6ad44 100644 --- a/mnoskov/postgresql/6. Подзапросы и CTE/DQL_cte_practice.sql +++ b/mnoskov/postgresql/6. Подзапросы и CTE/DQL_cte_practice.sql @@ -26,7 +26,7 @@ WHERE NOT EXISTS ( WHERE u.id = o.user_id ) --- Работает быстрее чем NOT IN +-- NOT EXISTS безопаснее в плане NULL, и часто планируется лучше чем NOT IN -- Определить какое количество людей не делают заказы, и кинуть им например купон на скидку на первый заказ @@ -50,7 +50,7 @@ ORDER BY -- Задание 4 -WITH revenue_by_user AS ( +WITH revenue_user AS ( SELECT o.user_id, sum(oi.quantity * oi.price_at_purchase) AS total_revenue @@ -63,19 +63,19 @@ WITH revenue_by_user AS ( ) SELECT u.name, - rbu.total_revenue + ru.total_revenue FROM mnoskov.users u JOIN - revenue_by_user rbu ON u.id = rbu.user_id + revenue_user ru ON u.id = ru.user_id ORDER BY - rbu.total_revenue desc; + ru.total_revenue desc; -- Проще читать когда шаг «посчитать выручку по пользователям» вынесен отдельно -- Чтобы избежать дублирования импользуется CTE, а не простой подзапрос -- Задание 5 -WITH revenue_by_product AS ( +WITH revenue_product AS ( SELECT product_id, sum(quantity * price_at_purchase) AS product_revenue @@ -87,13 +87,13 @@ WITH revenue_by_product AS ( SELECT p.name, p.category, - rbp.product_revenue + rp.product_revenue FROM mnoskov.products p JOIN - revenue_by_product rbp ON p.id = rbp.product_id + revenue_product rp ON p.id = rp.product_id ORDER BY - rbp.product_revenue + rp.product_revenue LIMIT 3; -- Сначала удобнее считать агрегаты, чтобы код не выгляжел грооздким и чтобы в нем было легче разобраться -- Отличае в удобстве чтения и написания. И этот агрегат можно потом ещё и переиспользовать