Работа над ошибками: 'Синтаксис'.

Практика: 'JOIN' - 'Массивы, Map и вложенные структуры*' - 'Партиции' - 'Индексы'.
This commit is contained in:
mnoskov
2026-05-18 16:55:22 +03:00
parent 80d333fe52
commit ae208a76fb
8 changed files with 577 additions and 0 deletions
@@ -0,0 +1,215 @@
-- Задание 1
CREATE TABLE mnoskov.users
ON CLUSTER clickhouse_cluster
(
user_id UInt32,
name String,
age UInt8,
country String,
is_active Bool
)
ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/mnoskov/users',
'{replica}'
)
ORDER BY user_id;
INSERT INTO mnoskov.users
(user_id,name,age,country,is_active)
VALUES
(1,'Ivan',30,'RU',1),
(2,'Anna',25,'RU',1),
(3,'Petr',45,'RU',0),
(4,'Olga',35,'RU',1),
(5,'John',55,'US',1),
(6,'Alice',42,'US',0),
(7,'Tom',38,'US',1),
(8,'Lucas',28,'BR',1),
(9,'Maria',60,'BR',1),
(10,'Joao',27,'BR',0),
(11,'Kenji',33,'JP',1),
(12,'Yuki',29,'JP',0),
(13,'Chen',40,'CN',1),
(14,'Li',48,'CN',1),
(15,'Fatima',31,'AE',1),
(16,'Ahmed',36,'AE',1),
(17,'George',24,'US',1),
(18,'Nina',34,'RU',1),
(19,'Max',50,'DE',1),
(20,'Sophie',22,'DE',0);
SELECT * FROM mnoskov.users;
--1
SELECT
user_id,
age,
is_active
FROM
mnoskov.users
WHERE
is_active = TRUE
ORDER BY
age DESC
LIMIT 10;
--2
SELECT
name,
country
FROM
mnoskov.users
WHERE
country = 'RU'
ORDER BY
name;
--3
SELECT
user_id,
age,
is_active
FROM
mnoskov.users
WHERE
is_active = TRUE
LIMIT 10;
-- Данные вывелить так как лежат на диске.
--4
SELECT
country,
count() as cnt_users
FROM
mnoskov.users
GROUP BY
country;
--5
SELECT
country,
min(age) AS min_age,
max(age) AS max_age
FROM
mnoskov.users
GROUP BY
country;
--6
SELECT
country,
count() AS cnt_users
FROM
mnoskov.users
GROUP BY
country
ORDER BY
cnt_users DESC;
--Доп
SELECT
uniqExact(country),
uniq(country)
FROM
mnoskov.users;
-- uniqExact(country) - кол-во уникальных значений в колонке country. Но uniq работает также.
-- В инете написано что uniq быстрее.
-- Задание 2
CREATE TABLE mnoskov.events1
ON CLUSTER clickhouse_cluster
(
user_id UInt32,
event_time DateTime,
event_type String
)
ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/mnoskov/events1',
'{replica}'
)
ORDER BY(user_id,event_time);
INSERT INTO mnoskov.events1
(user_id,event_time,event_type)
VALUES
(1,'2025-07-17 09:00:00','click'),
(1,'2025-07-17 09:05:00','view'),
(1,'2025-07-17 09:10:00','purchase'),
(2,'2025-07-17 10:00:00','click'),
(2,'2025-07-17 10:05:00','click'),
(2,'2025-07-17 11:00:00','view'),
(3,'2025-07-16 12:00:00','view'),
(3,'2025-07-16 12:30:00','click'),
(3,'2025-07-17 08:00:00','purchase'),
(4,'2025-07-17 13:00:00','click'),
(4,'2025-07-17 14:00:00','view'),
(4,'2025-07-17 15:00:00','view'),
(5,'2025-07-16 20:00:00','view'),
(5,'2025-07-17 01:00:00','click'),
(5,'2025-07-17 06:00:00','purchase'),
(6,'2025-07-17 07:30:00','view'),
(6,'2025-07-17 08:45:00','click'),
(7,'2025-07-16 23:59:59','click'),
(7,'2025-07-17 00:01:00','purchase'),
(7,'2025-07-17 10:10:00','view');
SELECT * FROM mnoskov.events1;
--1
SELECT
user_id,
event_time,
event_type,
count() OVER(PARTITION BY user_id ORDER BY event_time) AS com_users
FROM
mnoskov.events1;
--2
SELECT
user_id,
event_time,
event_type,
row_number() OVER (PARTITION BY user_id ORDER BY event_time) rn,
dense_rank() OVER (PARTITION BY user_id ORDER BY event_time) dr,
count() OVER(PARTITION BY user_id ORDER BY event_time) AS c,
sum(1) OVER(PARTITION BY user_id ORDER BY event_time) AS s
FROM
mnoskov.events1;
--3
SELECT
user_id,
event_time,
event_type,
count() OVER(PARTITION BY user_id ORDER BY event_time ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS com_users,
count() OVER(PARTITION BY user_id ORDER BY event_time ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS com_users2
FROM
mnoskov.events1;
-- все четенько работает, никаких ошибкок нет
--4-5-6
WITH recent_events AS (
SELECT
user_id,
event_time,
event_type
FROM
mnoskov.events1
WHERE
event_time < now() - INTERVAL 1 DAY
)
SELECT
user_id,
count(*) AS cnt_user_actions
FROM
recent_events
GROUP BY
user_id
ORDER BY
cnt_user_actions DESC
LIMIT
5;
-- не понял, как сделать 6 пункт.
-- Ответ на вопрос - ну да - поддерживает.
@@ -0,0 +1,57 @@
-- Задание 1
SELECT
pro.product_id,
pro.name,
pri.price
FROM
mnoskov.products pro
ANY LEFT JOIN
mnoskov.prices pri ON pro.product_id = pri.product_id;
-- 2 Выберется случайная из цен.
-- 3 ALL LEFT JOIN - работает также как и LEFT JOIN. Его избегают потому что он тянет больше строк в оперативную память.
-- Задание 2
SELECT
o.time,
o.symbol,
o.size,
t.price
FROM
mnoskov.orders o
ASOF JOIN
mnoskov.ticks t ON o.symbol = t.symbol AND t.time <= o.time
WHERE symbol = 'AAPL';
-- Потому что дата сделки и дата последней фиксации цены - разные.
-- Задание 3
SELECT
user_id,
name
FROM
mnoskov.users
WHERE user_id IN (
SELECT user_id
FROM mnoskov.payments
WHERE amount > 1000
);
-- 3 Потому что это фильтрация по существованию. Как оптимизируется не знаю, наверное как подзапрос.
-- Задание 4
SELECT
bl.user_id,
u.name AS user_name,
bl.event_time,
bl.event_type
FROM
mnoskov.big_logs bl
JOIN
mnoskov.users u ON bl.user_id = u.user_id;
-- 2 потому что таблица users меньше, а значит в оператику полетит меньше данных.
-- 3 если user_id уникален, то нужно выбирать ALL, так как дублей нет. В текущем задании дубли есть, но мы все равно выбираем ALL, тк нужно вывести имя для каждого лога а не юзера.
@@ -0,0 +1,44 @@
-- Задание 1
--1-2
SELECT
user_id,
tags,
indexOf(tags, 'promo') AS pos_promo
FROM
mnoskov.events
WHERE
has(tags, 'promo');
--3
SELECT
user_id,
arrayJoin(tags) AS tag
FROM
mnoskov.events;
-- Задание 2
--1
SELECT user_id, scores['math'] FROM mnoskov.metrics;
--2
SELECT user_id, mapValues(scores) FROM mnoskov.metrics;
-- Заданик 3
--1
SELECT * FROM mnoskov.users_nested WHERE has(contacts.type, 'email');
--2
SELECT
id,
name,
c.type,
c.value
FROM
mnoskov.users_nested
ARRAY JOIN
contacts AS c;