Merge pull request 'test commit' (#36) from anton into main
Reviewed-on: https://gitea.de-infra.servehttp.com/de-infrastructure/DWH/pulls/36
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 230 KiB |
|
After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 189 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 174 KiB |
|
After Width: | Height: | Size: 179 KiB |
@@ -0,0 +1,53 @@
|
|||||||
|
/*Задача 1: Какой будет порядок выполнения у запросов?
|
||||||
|
|
||||||
|
SELECT name, age
|
||||||
|
FROM users
|
||||||
|
WHERE is_active = true AND country = 'Canada'
|
||||||
|
ORDER BY age
|
||||||
|
LIMIT 3;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
1. FROM users
|
||||||
|
2. WHERE is_active = true AND country = 'Canada'
|
||||||
|
3. SELECT name, age
|
||||||
|
4. ORDER BY age
|
||||||
|
5. LIMIT 3
|
||||||
|
|
||||||
|
/*
|
||||||
|
SELECT country, COUNT(*) AS active_users
|
||||||
|
FROM users
|
||||||
|
WHERE is_active = true
|
||||||
|
GROUP BY country
|
||||||
|
HAVING COUNT(*) > 1;
|
||||||
|
*/
|
||||||
|
|
||||||
|
1. FROM users
|
||||||
|
2. WHERE is_active = true
|
||||||
|
3. GROUP BY country
|
||||||
|
4. HAVING COUNT(*) > 1
|
||||||
|
5. SELECT country, COUNT(*) AS active_users
|
||||||
|
|
||||||
|
/*
|
||||||
|
SELECT country, AVG(age) AS avg_age
|
||||||
|
FROM users
|
||||||
|
GROUP BY country
|
||||||
|
HAVING COUNT(*) >= 3 AND AVG(age) > 25;
|
||||||
|
*/
|
||||||
|
|
||||||
|
1. FROM users
|
||||||
|
2. GROUP BY country
|
||||||
|
3. HAVING COUNT(*) >= 3 AND AVG(age) > 25
|
||||||
|
4. SELECT country, AVG(age) AS avg_age
|
||||||
|
|
||||||
|
/*
|
||||||
|
SELECT name, age
|
||||||
|
FROM users
|
||||||
|
WHERE is_active = false AND age > 30
|
||||||
|
ORDER BY name;
|
||||||
|
*/
|
||||||
|
|
||||||
|
1. FROM users
|
||||||
|
2. WHERE is_active = false AND age > 30
|
||||||
|
3. SELECT name, age
|
||||||
|
4. ORDER BY name
|
||||||
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 205 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 206 KiB |
@@ -0,0 +1,104 @@
|
|||||||
|
-- Создание и заполнение таблицы
|
||||||
|
|
||||||
|
create table products_extended(
|
||||||
|
id INT primary key,
|
||||||
|
name TEXT,
|
||||||
|
category TEXT,
|
||||||
|
price DECIMAL,
|
||||||
|
in_stock BOOLEAN,
|
||||||
|
email_support TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO products_extended (id, name, category, price, in_stock, email_support) VALUES
|
||||||
|
(1, 'iPhone 14', 'smartphone', 799, TRUE, 'iphone@apple.com'),
|
||||||
|
(2, 'MacBook Air', 'laptop', 1199, FALSE, NULL),
|
||||||
|
(3, 'Galaxy S22', 'smartphone', 699, TRUE, 'galaxy@support.com'),
|
||||||
|
(4, 'ThinkPad X1', 'laptop', 1399, TRUE, 'thinkpad@lenovo.com'),
|
||||||
|
(5, 'iPad Pro', 'tablet', 999, FALSE, 'ipad@apple.com'),
|
||||||
|
(6, 'Kindle Paperwhite', 'ebook_reader', 149, TRUE, NULL),
|
||||||
|
(7, 'Mi Band 7', 'smartwatch', 49, TRUE, 'miband@xiaomi.com'),
|
||||||
|
(8, 'Surface Pro', 'tablet', 1299, TRUE, 'surface@microsoft.com'),
|
||||||
|
(9, 'Honor Pad X9', 'tablet', 219, TRUE, 'honor@support.com'),
|
||||||
|
(10, 'Dell XPS 13', 'laptop', 1099, FALSE, 'dell@support.com');
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 1:
|
||||||
|
Выведи все товары, которые:
|
||||||
|
- в наличии
|
||||||
|
- НЕ относятся к `smartwatch` и `ebook_reader`
|
||||||
|
- стоят от 300 до 1300
|
||||||
|
И для них посчитай:
|
||||||
|
1. price с наценкой 10%
|
||||||
|
2. price с НДС 20%
|
||||||
|
3. Статус: если email_support IS NULL, подставь нет почты, иначе — сам email
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
select name, category, price, price * 1.1 as price_with_markup, price * 1.2 as price_with_vat, coalesce(email_support, 'нет почты') as status
|
||||||
|
from products_extended
|
||||||
|
where in_stock = true and category not in ('smartwatch', 'ebookreader') and price between 300 and 1300;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 2:
|
||||||
|
Найти все товары:
|
||||||
|
1. У которых цена меньше 150 или больше 1200
|
||||||
|
2. У которых** есть email поддержки
|
||||||
|
Для каждого выведи:
|
||||||
|
1. Название
|
||||||
|
2. Категорию
|
||||||
|
3. Email
|
||||||
|
4. Цену с прибавкой 25%
|
||||||
|
5. Отметку `premium` — если цена > 1000
|
||||||
|
*/
|
||||||
|
|
||||||
|
select name, category, email_support, price * 1.25 as price_25, (price> 1000) as premium
|
||||||
|
from products_extended
|
||||||
|
where (price < 150 or price > 1200) and email_support is not null
|
||||||
|
order by premium;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 3:
|
||||||
|
Найди все товары:
|
||||||
|
- где категория — `smartphone`, `laptop`, `tablet`
|
||||||
|
- название НЕ содержит `'i'` (чтобы исключить Apple)
|
||||||
|
- цена от 500 до 1300
|
||||||
|
Выведи:
|
||||||
|
- `id`, `name`, `category`, `price`
|
||||||
|
- отсортируй по `id`
|
||||||
|
*/
|
||||||
|
|
||||||
|
select id, name, category, price
|
||||||
|
from products_extended
|
||||||
|
where category in('smartphone', 'laptop', 'tablet') and name not like '%i%' and price between 500 and 1300
|
||||||
|
order by id desc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 4:
|
||||||
|
Найди товары, у которых:
|
||||||
|
- email_support IS NULL
|
||||||
|
- они в наличии
|
||||||
|
- стоят менее 800
|
||||||
|
Выведи:
|
||||||
|
- `name`, `category`, `price`
|
||||||
|
- добавь колонку `comment`: `'нет поддержки'`
|
||||||
|
*/
|
||||||
|
|
||||||
|
select name, category, price, coalesce (email_support, 'нет поддержки') as comment
|
||||||
|
from products_extended
|
||||||
|
where email_support is null and in_stock is not null and price < 800;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 5:
|
||||||
|
Найди товары, у которых:
|
||||||
|
- название заканчивается на `'Pro'` ИЛИ содержит `'X'` внутри (например, `X1`, `XPS`)
|
||||||
|
- в наличии
|
||||||
|
- с ценой > 700
|
||||||
|
Выведи:
|
||||||
|
- `name`, `category`, `price`
|
||||||
|
- флаг `premium` — `true`, если `price > 1000`, иначе `false`
|
||||||
|
*/
|
||||||
|
|
||||||
|
select name, category, price, (price>1000) as premium
|
||||||
|
from products_extended
|
||||||
|
where (name like '%Pro%' or name like '%X%') and in_stock is true and price > 700
|
||||||
|
order by price desc;
|
||||||
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 197 KiB |
|
After Width: | Height: | Size: 174 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 179 KiB |
|
After Width: | Height: | Size: 206 KiB |
@@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE test_db;#
|
||||||
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 175 KiB |
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
Задача 1:
|
||||||
|
|
||||||
|
Для каждой категории показать 2 строки:
|
||||||
|
- Самый дорогой товар с email'ом
|
||||||
|
- Самый дорогой товар без email'а
|
||||||
|
*/
|
||||||
|
with with_mail as (
|
||||||
|
select category, name, price, email_support
|
||||||
|
from (
|
||||||
|
select category, name, price, email_support,
|
||||||
|
row_number() over (partition by category order by price desc) as rn
|
||||||
|
from products_extended
|
||||||
|
where email_support is not null
|
||||||
|
) t
|
||||||
|
where rn = 1
|
||||||
|
),
|
||||||
|
without_mail as (
|
||||||
|
select category, name, price, email_support
|
||||||
|
from (
|
||||||
|
select category, name, price, email_support,
|
||||||
|
row_number() over (partition by category order by price desc) as rn
|
||||||
|
from products_extended
|
||||||
|
where email_support is null
|
||||||
|
) t
|
||||||
|
where rn = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
select * from with_mail
|
||||||
|
union all
|
||||||
|
select * from without_mail
|
||||||
|
order by category;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 2:
|
||||||
|
|
||||||
|
Для каждого товара показать:
|
||||||
|
|
||||||
|
- `name` — название товара
|
||||||
|
- `category` — категория товара
|
||||||
|
- `price` — цена текущего товара
|
||||||
|
- `next_price` — цена следующего товара внутри той же категории, упорядоченного по цене
|
||||||
|
- `diff` — разница между ценой текущего товара и ценой следующего товара
|
||||||
|
(`price - next_price`)
|
||||||
|
*/
|
||||||
|
|
||||||
|
with t as(
|
||||||
|
select name, category, price,
|
||||||
|
lead(price) over (partition by category order by price) as next_price
|
||||||
|
from products_extended)
|
||||||
|
select name, category, price, next_price,
|
||||||
|
price - next_price as diff
|
||||||
|
from t order by category;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 3:
|
||||||
|
|
||||||
|
Показать `category`, `name`, `price`, `cumulative_sales`
|
||||||
|
|
||||||
|
Где `cumulative_sales` — это сумма `price` **внутри категории** по мере возрастания цены
|
||||||
|
*/
|
||||||
|
|
||||||
|
select category, name, price,
|
||||||
|
sum(price) over (partition by category order by price) as cumulative_sales
|
||||||
|
from products_extended;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Задача 4:
|
||||||
|
|
||||||
|
Вывести `category`, `name`, `price`, `avg_price`, `is_above_avg`
|
||||||
|
|
||||||
|
Где `avg_price` — средняя цена по категории
|
||||||
|
|
||||||
|
`is_above_avg = true`, если `price > avg_price`
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
with t as(
|
||||||
|
select category, name, price,
|
||||||
|
round(avg(price) over (partition by category), 1) as avg_price
|
||||||
|
from products_extended)
|
||||||
|
select category, name, price, avg_price,
|
||||||
|
price > avg_price as is_above_avg
|
||||||
|
from t order by category;
|
||||||
|
|
||||||