Привіт, усім!
У цій частині я поділюсь результатами мого проекту стажування щодо процесу аналізу даних за допомогою мови запитів SQL.
Набір даних, який використовувався, походить з Kaggle: Найбільший набір даних електронної комерції Пакистану, з деякими модифікаціями.
Використані набори даних:
order_detail
sku_detail
customer_detail
payment_detail
Опис наборів даних:
order_detail
Таблиця:
id
→ Унікальний ідентифікатор замовлення.customer_id
→ Унікальний ідентифікатор клієнта.order_date
→ Дата транзакції.sku_id
→ Унікальний ідентифікатор продукту (SKU = одиниця збереження запасів).price
→ Ціна, зазначена на етикетці товару.qty_ordered
→ Кількість товарів, яку придбав клієнт.before_discount
→ Загальна ціна продукту (price * qty_ordered
).discount_amount
→ Загальна сума знижки для товару.after_discount
→ Загальна ціна продукту після знижки.is_gross
→ Вказує на те, що клієнт ще не оплатив замовлення.is_valid
→ Вказує на те, що клієнт здійснив платіж.is_net
→ Вказує на те, що транзакція завершена.payment_id
→ Унікальний ідентифікатор способу оплати.
sku_detail
Таблиця:
id
→ Унікальний ідентифікатор продукту (використовується як ключ для з'єднань).sku_name
→ Назва продукту.base_price
→ Ціна, зазначена на етикетці товару.cogs
→ Собівартість проданого товару (вартість продажу однієї одиниці продукту).category
→ Категорія продукту.
customer_detail
Таблиця:
id
→ Унікальний ідентифікатор клієнта.registered_date
→ Дата реєстрації клієнта як учасника.
payment_detail
Таблиця:
id
→ Унікальний ідентифікатор способу оплати.payment_method
→ Спосіб оплати.
Використовуючи вищезгадані набори даних, ми можемо виконати наступний аналіз:
Питання 1:
У 2021 році в який місяць загальна сума транзакцій (after_discount
) була найвищою? Використовуйте is_valid = 1
для фільтрації даних транзакцій.
transaksi (afterdiscount) paling besar? Gunakan isvalid = 1 untuk memfilter data transaksi.
-- No. 1
SELECT
TO_CHAR(order_date, 'Month') month_2021,
ROUND(SUM(after_discount)) total_sales
FROM
order_detail
WHERE
EXTRACT(YEAR FROM order_date) = 2021
AND is_valid = 1
GROUP BY 1
ORDER BY 2 DESC;
Пояснення:
TO_CHAR(order_date, 'Month')
: Витягує місяць з колонкиorder_date
у вигляді рядка (імена місяців).ROUND(SUM(after_discount))
: Обчислює загальні продажі після знижок для всіх транзакцій, округлюючи їх до найближчого цілого числа.WHERE EXTRACT(YEAR FROM order_date) = 2021 AND is_valid = 1
: Фільтрує транзакції, що відбулися у 2021 році та є дійсними.GROUP BY 1
: Групує дані за першим стовпцем (місяць).ORDER BY 2 DESC
: Сортує результати за другим стовпцем (total_sales
) у спадному порядку.
Висновок:
Місяць з найвищою загальною сумою транзакцій (after_discount
) у 2021 році — це листопад.
Питання 2:
У 2021 році в який місяць були найвищими такі показники:
- Загальна кількість унікальних клієнтів,
- Загальна кількість унікальних замовлень,
- Загальна кількість проданих товарів?
Використовуйте is_valid = 1
для фільтрації даних транзакцій.
SQL Запит:
SELECT
TO_CHAR(order_date, 'Month') AS month_2021,
COUNT(DISTINCT customer_id) AS total_customers,
COUNT(DISTINCT id) AS total_orders,
SUM(qty_ordered) AS total_quantity
FROM
order_detail
WHERE
EXTRACT(YEAR FROM order_date) = 2021
AND is_valid = 1
GROUP BY 1
ORDER BY 2 DESC;
Пояснення:
SELECT TO_CHAR(order_date, 'Month') AS month_2021
використовується для вибору стовпців для отримання. У цьому випадку вибраний стовпець — місяць у вигляді повної назви місяця у 2021 році, і він отримує псевдонімmonth_2021
.
2.
COUNT(DISTINCT customer_id) AS total_customers
використовується для обчислення кількості унікальних клієнтів (без дублікатів), які здійснили транзакції в кожному місяці 2021 року. Кількість унікальних клієнтів зберігається в новому стовпці з псевдонімомtotal_customers
.COUNT(DISTINCT id) AS total_orders
використовується для обчислення кількості унікальних замовлень, які відбулися в кожному місяці 2021 року. Кількість унікальних замовлень зберігається в новому стовпці з псевдонімомtotal_orders
.SUM(qty_ordered) AS total_quantity
використовується для підсумовування кількості проданих товарів у кожному місяці 2021 року. Загальна кількість товарів зберігається в новому стовпці з псевдонімомtotal_quantity
.FROM order_detail
використовується для вказівки таблиці, з якої будуть отримані дані, в цьому випадку це таблицяorder_detail
.WHERE EXTRACT(YEAR FROM order_date) = 2021 AND is_valid = 1
використовується для фільтрації даних, щоб включити тільки транзакції, які відбулися в 2021 році і мають значенняis_valid
рівне 1.GROUP BY 1
використовується для групування результатів за першим стовпцем, яким є стовпецьmonth_2021
.ORDER BY 2 DESC
використовується для сортування результатів за другим стовпцем (total_customers
) у спадному порядку.
Отже, цей SQL-запит виведе інформацію про кількість клієнтів, кількість замовлень і загальну кількість проданих товарів для кожного місяця 2021 року з таблиці order_detail
, відсортовану за місяцем з найбільшою кількістю клієнтів.
Висновок:
Місяцем з найбільшою кількістю унікальних клієнтів, унікальних замовлень і проданих товарів у 2021 році є листопад.
Питання 3:
У транзакціях, що відбулися в 2022 році, яка категорія генерувала найвищу суму транзакцій? Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No. 3
SELECT
sku.category,
ROUND(SUM(after_discount)) total_sales
FROM
order_detail ord
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
EXTRACT(YEAR FROM order_date) = 2022
AND is_valid = 1
GROUP BY 1
ORDER BY 2 DESC;
Пояснення:
SELECT category, ROUND(SUM(after_discount)) AS total_sales
використовується для вибору стовпцяcategory
з таблиці та обчислення сумиafter_discount
з таблиціorder_detail
. Результат округлюється та отримує псевдонімtotal_sales
.LEFT JOIN sku_detail sku ON sku.id = ord.sku_id
використовується для з'єднання таблицьorder_detail
таsku_detail
на основі співпадіння стовпцяid
.WHERE EXTRACT(YEAR FROM order_date) = 2022 AND is_valid = 1
використовується для фільтрації транзакцій, що відбулися в 2022 році зis_valid
, рівним 1 (дійсні транзакції).GROUP BY 1
використовується для групування результатів за категорією з таблиціsku_detail
.ORDER BY 2 DESC
використовується для сортування результатів у спадному порядку на основі значенняtotal_sales
.
Використовуючи цей SQL-запит, ми можемо визначити, яка категорія товарів генерувала найбільшу суму транзакцій у 2022 році при умові is_valid = 1
.
Висновок:
Категорія Мобільні телефони та планшети має найвищу суму транзакцій порівняно з іншими категоріями.
Питання 4:
Порівняйте значення транзакцій кожної категорії в 2021 та 2022 роках. Визначте, які категорії зазнали збільшення, а які — зменшення суми транзакцій з 2021 по 2022 рік. Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No.
4
WITH tab_total AS ( WITH tab_sales AS (
SELECT
sku.category AS category_name,
ROUND(SUM(CASE WHEN EXTRACT(YEAR FROM order_date) = 2021 THEN after_discount ELSE 0 END)) AS total_sales_2021,
ROUND(SUM(CASE WHEN EXTRACT(YEAR FROM order_date) = 2022 THEN after_discount ELSE 0 END)) AS total_sales_2022
FROM
order_detail ord
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
is_valid = 1
GROUP BY 1
ORDER BY 2 DESC )
SELECT
tab_sales.*,
total_sales_2022 - total_sales_2021 increase_sales
FROM
tab_sales
ORDER BY increase_sales DESC )
SELECT * FROM tab_total;
Пояснення:
WITH
використовується для створення тимчасової таблиці (tab_total
абоtab_sales
), яка містить загальні продажі для кожної категорії в 2021 році. Ця тимчасова таблиця потім використовується в основному запиті для відображення загальних продажів за 2021 та 2022 роки для кожної категорії.ROUND(SUM(CASE WHEN EXTRACT(YEAR FROM order_date) = 2021 THEN after_discount ELSE 0 END)) AS total_sales_2021
: Це обчислює загальні продажі за 2021 рік для відповідної категорії продукту. ФункціяSUM
підсумовує значенняafter_discount
для рядків, що відповідають транзакціям у 2021 році. ОператорCASE
забезпечує, щоб враховувалися тільки транзакції з 2021 року, а інші транзакції рахуються як нуль (0). Результат потім округлюється за допомогою функціїROUND
.LEFT JOIN sku_detail sku ON sku.id = ord.sku_id
: ВикористовуючиLEFT JOIN
, таблицяsku_detail
приєднується, забезпечуючи включення всіх записів з таблиціsku_detail
, навіть якщо немає відповідних рядків у таблиціorder_detail
. Якщоsku_id
в таблиціorder_detail
не збігається з жоднимid
в таблиціsku_detail
, відповідні значення з таблиціorder_detail
будутьNULL
.WHERE is_valid = 1
: Це фільтрує лише дійсні транзакції.GROUP BY 1
: Це групує результати за першою колонкою, якою є стовпець категорії.ORDER BY 2 DESC
: Це сортує результати в спадному порядку за значенням у стовпціtotal_sales_2021
.tab_sales.*, total_sales_2022 - total_sales_2021
: Це вибирає всі стовпці з таблиціtab_sales
та обчислює різницю між загальними продажами в 2022 та 2021 роках, зберігаючи результат у стовпціincrease_sales
.ORDER BY 4 DESC
: Це сортує результати в спадному порядку за стовпцемincrease_sales
.
Використовуючи цей SQL-запит, ми можемо визначити, які категорії продуктів зазнали збільшення або зменшення суми транзакцій з 2021 по 2022 рік при умові is_valid = 1
. Категорії, що зазнали збільшення у сумі транзакцій, будуть на вершині результатів запиту, а категорії з зменшенням — внизу.
Згідно з отриманими даними, категорії, які зазнали збільшення суми транзакцій з 2021 по 2022 рік:
- Мобільні телефони та планшети
- Жіноча мода
- Розваги
- Побутова техніка
- Супермаркети
- Обчислювальна техніка
- Діти та малюки
- Краса та догляд
- Охорона здоров'я та спорт
- Дім та інтер'єр
- Школа та освіта
А категорії, що зазнали зменшення:
- Чоловіча мода
- Книги
- Согхат
- Інші
Питання 5:
Відобразіть топ-10 найменувань товарів (разом з їх категоріями) на основі суми транзакцій, що відбулися в 2022 році. Також відобразіть загальну кількість унікальних клієнтів, кількість унікальних замовлень та загальну кількість товарів. Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No.
5
SELECT
sku.sku_name,
sku.category,
ROUND(SUM(after_discount)) total_sales,
COUNT(DISTINCT ord.customer_id) AS total_customers,
COUNT(DISTINCT ord.id) AS total_orders,
SUM(qty_ordered) AS total_quantity
FROM
order_detail ord
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
EXTRACT(YEAR FROM order_date) = 2022
AND is_valid = 1
GROUP BY
1,2
ORDER BY 3 DESC
LIMIT 10;
Пояснення:
- SELECT sku.sku_name, sku.category: Цей запит вибирає стовпці з назвами продуктів і категоріями з таблиці
sku_detail
. - ROUND(SUM(afterdiscount)) AS totalsales: Обчислює загальні продажі для кожного товару, підсумовуючи значення стовпця
after_discount
з таблиціorder_detail
та округлюючи їх до найближчого цілого числа. - COUNT(DISTINCT ord.customerid) AS totalcustomers: Підраховує кількість унікальних клієнтів, використовуючи унікальні значення
customer_id
в таблиціorder_detail
. - COUNT(DISTINCT ord.id) AS total_orders: Підраховує кількість унікальних замовлень, використовуючи унікальні значення
id
в таблиціorder_detail
. - SUM(qtyordered) AS totalquantity: Підсумовує кількість замовлених товарів для кожного SKU, використовуючи значення стовпця
qty_ordered
в таблиціorder_detail
. - FROM orderdetail ord LEFT JOIN skudetail sku ON sku.id = ord.sku_id: Використовується
LEFT JOIN
для об'єднання таблицьorder_detail
таsku_detail
на основі стовпцяsku_id
, щоб отримати деталі продукту. - WHERE EXTRACT(YEAR FROM orderdate) = 2022 AND isvalid = 1: Фільтрує дані, щоб включити лише транзакції, що відбулися в 2022 році і мають значення
is_valid
рівне 1 (дійсні транзакції). - GROUP BY 1,2: Групує результати за першими двома стовпцями, якими є
sku_name
таcategory
. - ORDER BY 3 DESC: Сортує результати за третьою колонкою, якою є
total_sales
, у спадному порядку, щоб продукти з найбільшими продажами були на початку. - LIMIT 10: Обмежує результат до 10 рядків.
Отже, цей SQL-запит виводить топ-10 товарів за сумою транзакцій у 2022 році, разом із кількістю унікальних клієнтів, унікальних замовлень та загальною кількістю замовлених товарів для кожного SKU.
Висновок:
З таблиці можна визначити 10 продуктів з найбільшою кількістю транзакцій у 2022 році.
Питання 6:
Відобразіть топ-5 найбільш популярних способів оплати, що використовувалися в 2022 році (на основі кількості унікальних замовлень). Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No. 6
SELECT
pay.payment_method,
COUNT(DISTINCT ord.id) AS total_orders
FROM
order_detail ord
LEFT JOIN
payment_detail pay
ON pay.id = ord.payment_id
WHERE
EXTRACT(YEAR FROM order_date) = 2022
AND is_valid = 1
GROUP BY
1
ORDER BY
2 DESC
LIMIT 5;
Пояснення:
- Спочатку ми вибираємо дані з таблиці
order_detail
, використовуючи умовуWHERE
з фільтромEXTRACT(YEAR FROM order_date) = 2022
для обмеження транзакціями, що відбулися в 2022 році, а такожis_valid = 1
для забезпечення дійсності даних. - Потім ми групуємо дані за стовпцем
payment_method
за допомогою командиGROUP BY
. - Далі ми сортуємо результати запиту за кількістю замовлень (
total_orders
) у спадному порядку за допомогоюORDER BY 2 DESC
.
Оскільки ми хочемо відобразити лише топ-5 результатів, ми використовуємо конструкціюLIMIT 5
.
Отже, результати запиту покажуть топ-5 найбільш популярних способів оплати, що використовувалися в 2022 році, разом з кількістю унікальних замовлень для кожного способу оплати.
Питання 7:
Відсортуйте ці 5 продуктів на основі їхньої вартості транзакцій:
a. Samsung
b. Apple
c. Sony
d. Huawei
e. Lenovo
Використовуйте is_valid = 1
для фільтрації даних транзакцій.
Пояснення:
Запит групує продажі продуктів на основі назв продуктів, що містять конкретні ключові слова, такі як "Samsung", "Apple", "Sony", "Huawei" або "Lenovo", використовуючи функцію CASE
та LIKE
. Потім запит обчислює загальні продажі для кожного продукту у 2022 році та вставляє їх у тимчасову таблицю під назвою tab_sales
.
Після цього запит вибирає дані з tab_sales
, фільтруючи рядки, де стовпець 'product' не є NULL
. Це робиться для того, щоб усунути рядки без категорій продуктів (оскільки вони не відповідають заданим ключовим словам). Нарешті, запит сортує дані за загальними продажами у спадному порядку за допомогою конструкції ORDER BY
.
Питання 8:
Створіть порівняння значень прибутку за 2021 та 2022 роки для кожної категорії. Потім обчисліть відсоткову різницю в прибутку між 2021 та 2022 роками.
(Прибуток = afterdiscount — (cogs * qtyordered))
Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No. 8
WITH profit_table AS (
SELECT
sku.category,
EXTRACT(YEAR FROM order_date) AS year_order,
SUM(after_discount - (cogs * qty_ordered)) AS profit
FROM
order_detail ord
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
is_valid = 1
AND (EXTRACT(YEAR FROM order_date) = 2021
OR EXTRACT(YEAR FROM order_date) = 2022)
GROUP BY
sku.category, year_order
ORDER BY
profit
),
year_profit AS (
SELECT
category,
ROUND(SUM(CASE
WHEN (year_order = 2021) THEN profit
ELSE NULL
END)) AS year_2021,
ROUND(SUM(CASE
WHEN (year_order = 2022) THEN profit
ELSE NULL
END)) AS year_2022
FROM
profit_table
GROUP BY
category
)
SELECT
*,
ROUND(((year_2022 / year_2021) - 1) * 100) AS increase_profit
FROM
year_profit
ORDER BY
increase_profit DESC;
Цей запит є виразом Common Table Expression (CTE), що створює таблицю profit_table
, яка містить категорії продуктів, роки транзакцій та загальні прибутки від транзакцій у 2021 та 2022 роках. Потім CTE profit_table
використовується в іншому CTE під назвою year_profit
, який генерує таблицю з категоріями продуктів, загальним прибутком за 2021 рік та загальним прибутком за 2022 рік.
Після цього обчислюється відсоткова різниця в прибутку між 2021 та 2022 роками за формулою ((year_2022 / year_2021) - 1) * 100
, і результат відображається у стовпці increase_profit
.
Нарешті, результат з CTE year_profit
відображається, відсортований за відсотковою різницею в прибутку від найбільшого до найменшого.
Питання 9:
Відобразіть топ-5 SKU з найбільшим внеском у прибуток у 2022 році на основі категорії з найбільшим зростанням прибутку з 2021 по 2022 рік (на основі результатів з пункту 8). Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No.
9
WITH profit_table AS (
SELECT
ord.id,
sku.sku_name,
ord.after_discount - (cogs * qty_ordered) AS profit
FROM
order_detail ord
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
is_valid = 1
AND (EXTRACT(YEAR FROM order_date) = 2021
OR EXTRACT(YEAR FROM order_date) = 2022)
AND sku.category = 'Women Fashion'
)
SELECT
sku_name,
SUM(profit) AS total_profit
FROM
profit_table
GROUP BY
sku_name
ORDER BY
total_profit DESC
LIMIT 5;
Цей запит має на меті відобразити топ-5 SKU з найбільшим внеском у прибуток у 2022 році на основі категорії з найбільшим зростанням прибутку з 2021 по 2022 рік, використовуючи фільтр is_valid = 1
, щоб забезпечити обробку лише дійсних даних транзакцій.
Спочатку створюється вираз Common Table Expression (CTE) під назвою profit_table
, що містить ID замовлення, назву SKU та прибуток, обчислений за формулою after_discount - (cogs * qty_ordered)
. Дані отримуються тільки за 2021 та 2022 роки, і обробляються лише SKU з категорії «Жіноча мода».
Далі виконується запит для вибору sku_name
та total_profit
, обчисленого за допомогою функції SUM
на таблиці profit_table
. Дані групуються за sku_name
і сортуються за total_profit
у спадному порядку. Використовується функція LIMIT
для відображення лише перших 5 результатів.
Отже, цей запит генерує список з топ-5 SKU з найбільшим внеском у прибуток у 2022 році в категорії «Жіноча мода».
Питання 10:
Відобразіть кількість унікальних замовлень, використовуючи топ-5 способів оплати (з питання 6) за категоріями продуктів у 2022 році. Використовуйте is_valid = 1
для фільтрації даних транзакцій.
-- No. 10
SELECT
sku.category,
COUNT(DISTINCT CASE WHEN pay.payment_method = 'cod' THEN ord.id END) AS cod,
COUNT(DISTINCT CASE WHEN pay.payment_method = 'Easypay' THEN ord.id END) AS easypay,
COUNT(DISTINCT CASE WHEN pay.payment_method = 'Payaxis' THEN ord.id END) AS payaxis,
COUNT(DISTINCT CASE WHEN pay.payment_method = 'customercredit' THEN ord.id END) AS customercredit,
COUNT(DISTINCT CASE WHEN pay.payment_method = 'jazzwallet' THEN ord.id END) AS jazzwallet
FROM
order_detail AS ord
LEFT JOIN
payment_detail pay
ON pay.id = ord.payment_id
LEFT JOIN
sku_detail sku
ON sku.id = ord.sku_id
WHERE
is_valid = 1
AND EXTRACT(YEAR FROM order_date) = 2022
GROUP BY
sku.category
ORDER BY
cod DESC;
Цей запит використовується для обчислення кількості унікальних замовлень, використовуючи топ-5 способів оплати (Готівка при доставці, Easypay, Payaxis, Customer Credit, Jazzwallet) за категоріями продуктів у 2022 році.
Спочатку виконується LEFT JOIN
між таблицями order_detail
, payment_detail
і sku_detail
, щоб забезпечити включення даних з таблиці order_detail
, навіть якщо немає відповідних даних у таблицях payment_detail
або sku_detail
. Потім застосовується фільтр is_valid = 1
і вибираються лише дані з 2022 року.
Далі дані групуються (GROUP BY
) за категорією продуктів з таблиці sku_detail
, і обчислюється кількість унікальних замовлень (COUNT DISTINCT
) для кожного способу оплати за допомогою конструкції CASE WHEN
. Остаточні результати сортуються (ORDER BY
) за кількістю унікальних замовлень для способу оплати «Готівка при доставці» в спадному порядку.
З таблиці ми можемо побачити загальну кількість замовлень, що використовували топ-5 способів оплати для кожної категорії продуктів. При сортуванні за способом оплати «Готівка при доставці», категорія «Чоловіча мода» має найбільшу кількість замовлень, а категорія «Книги» — найменшу.
===============================================================
Це мій аналіз, заснований на 10 питаннях щодо бізнесу електронної комерції, що надається. Дякую за прочитання, сподіваюся, що він буде корисним для всіх 🙂
Перекладено з: Project Intern (PostgreSQL)