Задания SQL Flashcards
Решил
Условие:
В таблицу OrderPosition попали дубли. Необходимо их удалить (оставить любую строку) двумя способами
Ключ – order_id, product_id.
CREATE TABLE OrderPosition
(
order_id INTEGER,
product_id INTEGER,
quantity INTEGER,
product_price DECIMAL(20,6)
);
INSERT INTO OrderPosition (order_id, product_id, quantity, product_price)
VALUES
(14324, 459871, 1, 1540.99),
(14324, 459871, 1, 1540.99),
(14324, 459871, 1, 1540.99),
(14325, 98712, 3, 599.99),
(14325, 98712, 3, 599.99),
(16788, 598942, 1, 199.99),
(16789, 598943, 1, 5200.00);
Теги: #озон
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH duplicates AS (
SELECT
ctid,
ROW_NUMBER() OVER (
PARTITION BY order_id, product_id
ORDER BY ctid – жёстко базируем порядок на физическом адресе
) AS rn
FROM OrderPosition
)
DELETE FROM OrderPosition
WHERE ctid IN (
SELECT ctid
FROM duplicates
WHERE rn > 1 – удаляем все, у кого номер > 1
);
DELETE FROM OrderPosition
WHERE ctid NOT IN (
SELECT MIN(ctid)
FROM OrderPosition
GROUP BY order_id, product_id
);
Таблица 1 | Таблица 2
1 → 1
2 → 1
2 → 2
3 → 2
5 → 7
null → 8
null → null
Вывести результат join таблиц
Теги: #озон
Inner
1
1
2
2
2
2
Left
1
1
2
2
2
2
3
5
7
null
Right
1
1
2
2
2
2
7
8
null
Full
1
1
2
22
2
3
5
7
8
Null
Null
Null
Cross
есть 2 таблицы: в одной 5 записей, во второй 7
Вывести минимальное и максимальное количество строк при пересечении
inner join left join right cross full
Теги: #озон
inner join
0 35
left join
5 35
right
7 35
cross
35
full
7 35
ошибка синтаксиса
Вывести те значения, которые повторяются подряд не менее трех раз
CREATE TABLE IF NOT EXISTS Logs (num int);
INSERT INTO Logs (num) VALUES (134),(34),(4),(4),(4),(4),(4),(7),(14),(4),(4),(4),(2),(2),(2)
Теги: #ЛеруаМерлен
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH LaggedLogs AS (
SELECT num,
LAG(num, 1) OVER (ORDER BY (SELECT NULL)) AS prev1,
LAG(num, 2) OVER (ORDER BY (SELECT NULL)) AS prev2
FROM Logs
)
SELECT DISTINCT num
FROM LaggedLogs
WHERE num = prev1 AND num = prev2;
решил, но не с первого раза. Заруинил синтаксис
/*
order_id | store_id | item_id | supplier_id | price | quantity | dt
———+———-+———+————-+——-+———-+————————
1 | 1 | 10001 | 1 | 20 | 1 | 2023-10-11 13:54:00.000
2 | 2 | 10001 | 2 | 30 | 2 | 2023-11-11 17:14:05.000
2 | 3 | 10002 | 2 | 100 | 3 | 2023-09-01 09:32:50.000
3 | 3 | 10002 | 3 | 130 | 1 | 2023-10-21 14:51:45.000
supplier_id | supplier_name | supplier_type
————+—————+————–
1 | Supplier 1 | WAREHOUSE
2 | Supplier 2 | NULL
3 | Supplier 3 | SUPPLIER
4 | Supplier 4 | SUPPLIER
*/
–Напишите запрос, который для всех поставщиков с типом (supplier_type) отличным от “WAREHOUSE” выдаст идентификатор поставщика и сумму заказов у этого поставщика. В запросе не использовать оконные функции.
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
order_id INT,
store_id INT,
item_id INT,
supplier_id INT,
price DECIMAL,
quantity INT,
dt TIMESTAMP
);
INSERT INTO orders (order_id, store_id, item_id, supplier_id, price, quantity, dt) VALUES
(1, 1, 10001, 1, 20, 1, ‘2023-10-11 13:54:00’),
(2, 2, 10001, 2, 30, 2, ‘2023-11-11 17:14:05’),
(2, 3, 10002, 2, 100, 3, ‘2023-09-01 09:32:50’),
(3, 3, 10002, 3, 130, 1, ‘2023-10-21 14:51:45’);
CREATE TABLE suppliers (
supplier_id INT PRIMARY KEY,
supplier_name TEXT,
supplier_type TEXT
);
INSERT INTO suppliers (supplier_id, supplier_name, supplier_type) VALUES
(1, ‘Supplier 1’, ‘WAREHOUSE’),
(2, ‘Supplier 2’, NULL),
(3, ‘Supplier 3’, ‘SUPPLIER’),
(4, ‘Supplier 4’, ‘SUPPLIER’);
Теги: #ЛеруаМерлен
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
SELECT
supplier_type,
SUM(quantity * price) AS total
FROM
suppliers s
LEFT JOIN
orders o
ON
s.supplier_id = o.supplier_id
WHERE
s.supplier_type != ‘WAREHOUSE’ OR s.supplier_type IS NULL
GROUP BY
supplier_type
Ошибся в синтаксисе
SQL: Дан лог заездов/выездов в гостиницу. Лог состоит из записей (ts, user_id, event_type).
Надо найти сколько было постояльцев на каждый день существования гостиницы. Число постояльцев считается на конец дня. Вывести без дублей
CREATE TABLE hotel_log (
ts TIMESTAMP,
user_id INT,
event_type TEXT
);
INSERT INTO hotel_log (ts, user_id, event_type) VALUES
(‘2023-10-01 14:00:00’, 1, ‘CHECK_IN’),
(‘2023-10-01 18:30:00’, 2, ‘CHECK_IN’),
(‘2023-10-02 10:00:00’, 1, ‘CHECK_OUT’),
(‘2023-10-03 12:45:00’, 3, ‘CHECK_IN’),
(‘2023-10-03 22:00:00’, 2, ‘CHECK_OUT’),
(‘2023-10-05 09:00:00’, 3, ‘CHECK_OUT’),
(‘2023-10-06 16:15:00’, 4, ‘CHECK_IN’);
Теги: #Авито
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH cte AS (
SELECT
ts,
DATE(ts) AS day,
SUM(CASE WHEN event_type = ‘CHECK_IN’ THEN 1 ELSE -1 END)
OVER (ORDER BY DATE(ts)) AS total,
ROW_NUMBER() OVER (PARTITION BY DATE(ts) ORDER BY ts DESC) AS rn
FROM hotel_log
)
SELECT
ts, day, total
FROM
cte
WHERE
rn = 1
ORDER BY
day
***понимаю как делать срез. но не групировку
Вывести последний актуальный срез для каждого клиента (name, address), используя оконные функции и группировку. ID инкрементальный
drop table clients;
CREATE TABLE clients (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
address TEXT NOT NULL,
phone TEXT,
transaction_date TIMESTAMP DEFAULT now(),
transaction_amount DECIMAL
);
INSERT INTO clients (name, address, phone, transaction_date, transaction_amount) VALUES
(‘Alice’, ‘123 Main St’, ‘123-456-7890’, NULL, 120),
(‘Alice’, ‘123 Main St’, ‘123-456-7890’, ‘2024-01-10 14:45:00’, NULL),
(‘Alice’, ‘123 Main St’, ‘123-456-7890’, ‘2024-02-05 16:20:00’, 250),
(‘Alice’, ‘123 Main St’, ‘123-456-7890’, NULL, NULL),
(‘Bob’, ‘456 Elm St’, ‘987-654-3210’, ‘2023-11-22 10:15:00’, 180),
(‘Bob’, ‘456 Elm St’, ‘987-654-3210’, ‘2024-02-25 11:30:00’, NULL),
(‘Bob’, ‘456 Elm St’, ‘987-654-3210’, NULL, 220),
(‘Charlie’, ‘789 Oak St’, ‘555-123-4567’, ‘2023-10-03 09:00:00’, 310),
(‘Charlie’, ‘789 Oak St’, ‘555-123-4567’, NULL, 270),
(‘Charlie’, ‘789 Oak St’, ‘555-123-4567’, ‘2024-05-22 16:50:00’, NULL),
(‘David’, ‘321 Pine St’, ‘777-888-9999’, ‘2022-12-30 22:00:00’, 500),
(‘David’, ‘321 Pine St’, ‘777-888-9999’, NULL, 350),
(‘David’, ‘321 Pine St’, ‘777-888-9999’, ‘2023-09-29 19:30:00’, NULL),
(‘Eve’, ‘555 Birch St’, ‘222-333-4444’, ‘2021-07-04 18:45:00’, 150),
(‘Eve’, ‘555 Birch St’, ‘222-333-4444’, NULL, NULL),
(‘Eve’, ‘555 Birch St’, ‘222-333-4444’, ‘2023-05-09 20:30:00’, 275),
(‘Frank’, ‘987 Cedar St’, ‘999-000-1111’, ‘2023-03-12 06:30:00’, NULL),
(‘Frank’, ‘987 Cedar St’, ‘999-000-1111’, NULL, 220),
(‘Frank’, ‘987 Cedar St’, ‘999-000-1111’, ‘2024-02-18 08:40:00’, NULL);
(‘Frank’, ‘987 Cedar St’, ‘999-000-1111’, ‘2024-02-18 08:40:00’, NULL);
Теги: #Yandex
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Через групировку:
SELECT
name,
address,
(array_agg(phone ORDER BY id DESC))[1] AS phone,
(array_agg(transaction_date ORDER BY id DESC))[1] AS transaction_date,
EXTRACT(YEAR FROM (array_agg(transaction_date ORDER BY id DESC))[1]) AS year_cool,
EXTRACT(MONTH FROM (array_agg(transaction_date ORDER BY id DESC))[1]) AS month_cool,
SUM(transaction_amount) AS total
FROM clients
GROUP BY
name,
address,
EXTRACT(YEAR FROM transaction_date),
EXTRACT(MONTH FROM transaction_date)
ORDER BY
name,
year_cool,
month_cool;
Через оконку:
WITH ranked_clients AS (
SELECT
id,
name,
address,
phone,
transaction_date,
EXTRACT(YEAR FROM transaction_date) AS year_cool,
EXTRACT(MONTH FROM transaction_date) AS month_cool,
transaction_amount,
SUM(transaction_amount) OVER (
PARTITION BY name, EXTRACT(YEAR FROM transaction_date), EXTRACT(MONTH FROM transaction_date)
) AS total_transactions,
ROW_NUMBER() OVER (
PARTITION BY name, address
ORDER BY id DESC
) AS rn
FROM clients
)
SELECT
id,
name,
address,
phone,
transaction_date,
year_cool,
month_cool,
total_transactions
FROM ranked_clients
WHERE rn = 1
ORDER BY name, year_cool, month_cool;
если без агрегации:
WITH ranked_clients AS (
SELECT
id,
name,
address,
phone,
transaction_date,
ROW_NUMBER() OVER (
PARTITION BY name, address
ORDER BY id DESC
) AS rn
FROM clients
)
SELECT
id,
name,
address,
phone,
transaction_date
FROM ranked_clients
WHERE rn = 1
ORDER BY name, address;
SELECT
name,
address,
(array_agg(id ORDER BY id DESC))[1] AS id,
(array_agg(phone ORDER BY id DESC))[1] AS phone,
(array_agg(transaction_date ORDER BY id DESC))[1] AS transaction_date
FROM clients
GROUP BY name, address
ORDER BY name, address;
1) если будут пропуски в датах
Техника:
Генерация ряда дат с помощью generate_series (или аналогов в других СУБД). Кросс-присоединение (CROSS JOIN) клиентов и дат для получения полного набора данных. LEFT JOIN с исходными данными для объединения транзакций с полным рядом дат. Замена отсутствующих значений на 0 (COALESCE).
Ключевые функции и приёмы:
generate_series(start_date, end_date, interval '1 month') – создаёт последовательность месяцев. CROSS JOIN – помогает комбинировать клиентов и все возможные даты. LEFT JOIN – позволяет присоединить реальные данные, сохраняя строки с отсутствующими значениями. COALESCE(value, default) – заменяет NULL на 0.
2) нужно вычислить сумму не включая текущую транзакцию (только все предыдущие)
Техника:
Оконные функции (SUM() OVER()) для вычисления кумулятивных сумм. Использование рамок в оконных функциях (ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) для исключения текущей строки.
Ключевые функции и приёмы:
SUM(transaction_amount) OVER (PARTITION BY name ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) – суммирует все предыдущие транзакции, исключая текущую. PARTITION BY – группирует данные по клиенту. ORDER BY transaction_date – упорядочивает транзакции для правильного вычисления.
3) если будут null в суммах транзакций
Техника:
Использование COALESCE() для замены NULL на 0 в арифметических операциях. Группировка (GROUP BY) и агрегация (SUM()) с обработкой NULL.
Ключевые функции и приёмы:
COALESCE(transaction_amount, 0) – заменяет NULL на 0 перед суммированием. SUM(COALESCE(transaction_amount, 0)) – корректно обрабатывает суммы, даже если некоторые значения NULL.
Определите средний объем транзакций по месяцам за последний год
CREATE TABLE Transactions (TransactionID INT,
TransactionDate DATE, Amount DECIMAL);
INSERT INTO Transactions (TransactionID, TransactionDate, Amount) VALUES
(1, ‘2024-02-15’, 150.00),
(2, ‘2024-02-20’, 200.00),
(3, ‘2023-12-05’, 100.00),
(4, ‘2023-11-25’, 300.00),
(5, ‘2023-10-10’, 250.00),
(6, ‘2023-09-15’, 400.00),
(7, ‘2023-08-20’, 50.00),
(8, ‘2023-07-05’, 125.00),
(9, ‘2023-06-18’, 175.00),
(10, ‘2023-05-12’, 225.00);
Теги: #т1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
SELECT
EXTRACT(MONTH FROM TransactionDate) AS month,
AVG(Amount) AS avg_num
FROM
Transactions
WHERE
TransactionDate BETWEEN NOW() - INTERVAL ‘1 YEAR’ AND NOW()
GROUP BY
month
решил.
2) Вывести суммарный баланс по договорам Зарплат на конец 1 кв. 2024
drop table if exists deals;
create table deals (
id serial primary key,
deal_no varchar(50),
balance numeric(15,2),
report_date date
);
– Вставка тестовых данных
insert into deals (deal_no, balance, report_date) values
(‘D1001’, 5000.00, ‘2024-01-01’),
(‘D1001’, 5200.00, ‘2024-02-01’),
(‘D1001’, 5100.00, ‘2024-03-01’),
(‘D1002’, 7000.00, ‘2024-01-15’),
(‘D1002’, 6900.00, ‘2024-02-15’),
(‘D1003’, 8000.00, ‘2024-03-05’),
(‘D1003’, 8100.00, ‘2024-04-05’),
(‘D1003’, 8200.00, ‘2024-05-05’);
Теги: #т1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH cte AS (
SELECT
deal_no, balance, report_date,
ROW_NUMBER() OVER (PARTITION BY deal_no ORDER BY report_date) AS rn
FROM
deals
WHERE
report_date <= ‘2024-03-01’
)
SELECT
SUM(balance)
FROM
cte
WHERE
rn = 1
SELECT c.Customer, c.State, e.Entry
FROM Customer c
LEFT JOIN Entry e
ON c.Customer = e.Customer AND e.Category = ‘D’
SELECT Customer.Customer, Customer.State, Entry.Entry
FROM Customer
LEFT JOIN Entry
ON Customer.Customer = Entry.Customer
WHERE Entry.Category = ‘D’
в чем разница? #собес
Основное различие между двумя SQL-запросами заключается в порядке применения фильтрации (WHERE) и в логике обработки отсутствующих записей при использовании LEFT JOIN.
- Первый запрос
Разъяснение:
Условие e.Category = 'D' включено в ON-условие соединения. Это означает, что сначала происходит соединение таблиц на основе условия c.Customer = e.Customer и дополнительно фильтрации по e.Category = 'D'. Если для какого-то клиента не существует записи в таблице Entry с категорией 'D', то запись из Customer всё равно попадёт в результат, но значения из Entry будут NULL.
Ключевая особенность:
В результате будут все записи из Customer, независимо от того, есть ли совпадающие записи в Entry с категорией 'D'. Если таких записей нет, поля из Entry будут заполнены NULL.
- Второй запрос
Разъяснение:
Условие Entry.Category = 'D' вынесено в WHERE, а не в ON. Сначала выполняется соединение всех записей из таблицы Customer с таблицей Entry по условию Customer.Customer = Entry.Customer, а затем результат фильтруется с помощью WHERE Entry.Category = 'D'. Если для какого-то клиента нет записей с категорией 'D', то из-за условия в WHERE он будет удалён из результата.
Ключевая особенность:
В результате будут только те записи, у которых существует соответствующая запись в Entry с категорией 'D'. Если таких записей нет, строка из Customer вообще исключается из результата.
Чем отличаются эти 2 запроса и почему ? #ивитро
1.
SELECT*
FROMt2
LEFTJOINt1
ON t1.id=t2.id
ANDt1.nISnull
2.
SELECT*
FROMt2
LEFTJOINt1
ON t1.id=t2.id
WHEREt1.nISnull
ON t1.n IS NULL → фильтрация происходит во время соединения → строки t2 остаются всегда, но данные из t1 могут быть NULL (если пара не подошла).
WHERE t1.n IS NULL → фильтрация после соединения → строки t2, которые не нашли пару или у которых в t1 n IS NOT NULL, исключаются вообще.
Первый запрос (AND t1.n IS NULL в ON)
Условие t1.n IS NULL применяется только во время соединения. t2 сохраняет все строки, даже если t1 не заджойнился. Если t1 не нашлось, в результат попадёт t2 с NULL в t1.
Второй запрос (WHERE t1.n IS NULL)
LEFT JOIN сначала соединяет, затем WHERE фильтрует результат. Если у t2 нашлась пара в t1, но t1.n не NULL → строка отфильтруется. Если у t2 вообще нет пары в t1, то все поля t1 станут NULL → условие t1.n IS NULL выполнится, и такие строки останутся.
не решил из-за года дважды
Определите средний объем транзакций по месяцам за последний год
CREATE TABLE Transactions (TransactionID INT,
TransactionDate DATE, Amount DECIMAL);
Теги: #t1
CREATE TABLE Transactions (
TransactionID SERIAL PRIMARY KEY,
TransactionDate DATE NOT NULL,
Amount DECIMAL(15,2) NOT NULL CHECK (Amount >= 0)
);
INSERT INTO Transactions (TransactionDate, Amount) VALUES
(‘2025-02-15’, 120.50),
(‘2025-02-20’, 75.25),
(‘2025-01-10’, 200.00),
(‘2025-01-25’, 150.75),
(‘2025-12-05’, 300.40),
(‘2023-12-18’, 99.99),
(‘2023-11-12’, 250.60),
(‘2023-11-30’, 180.80),
(‘2023-10-07’, 320.00),
(‘2023-10-22’, 215.25),
(‘2023-09-09’, 400.75),
(‘2023-09-28’, 125.30),
(‘2023-08-14’, 175.90),
(‘2023-08-25’, 290.45),
(‘2025-07-06’, 110.80),
(‘2023-07-21’, 140.65),
(‘2023-06-11’, 310.00),
(‘2023-06-30’, 95.55),
(‘2023-05-15’, 275.75),
(‘2025-05-29’, 225.45),
(‘2023-04-10’, 180.20),
(‘2023-04-27’, 330.85),
(‘2023-03-05’, 420.90),
(‘2025-03-19’, 200.15),
(‘2023-02-22’, 150.40),
(‘2023-02-28’, 175.60),
(‘2023-01-13’, 135.75),
(‘2023-01-24’, 290.80);
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
SELECT
EXTRACT(YEAR FROM TransactionDate) AS year,
EXTRACT(MONTH FROM TransactionDate) AS month,
ROUND(AVG(Amount), 2)
FROM
Transactions
GROUP BY
year, month
ORDER BY
year, month
не решил
Рассчитайте среднюю зарплату в каждом отделе и определите–, какие сотрудники получают зарплату выше средней по своему отделу
CREATE TABLE Employees (
EmployeeID SERIAL PRIMARY KEY,
DepartmentID INT NOT NULL,
Salary DECIMAL(15,2) NOT NULL CHECK (Salary > 0)
);
INSERT INTO Employees (DepartmentID, Salary) VALUES
(1, 5000),
(1, 7000),
(1, 6000),
(2, 8000),
(2, 7500),
(2, 9000),
(3, 4000),
(3, 4500),
(3, 4800);
Теги: #t1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH AvgSalaries AS (
SELECT
DepartmentID,
AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY DepartmentID
)
SELECT
e.EmployeeID,
e.DepartmentID,
e.Salary,
a.AvgSalary
FROM Employees e
JOIN AvgSalaries a ON e.DepartmentID = a.DepartmentID
WHERE e.Salary > a.AvgSalary;
запутался немного
По каждому договору вывести последнюю запись, колонки - deal_NO, balance, report_date
CREATE TABLE Deals (
deal_NO INT NOT NULL,
balance DECIMAL(15,2) NOT NULL,
report_date DATE NOT NULL,
PRIMARY KEY (deal_NO, report_date) – Уникальная комбинация
);
INSERT INTO Deals (deal_NO, balance, report_date) VALUES
(101, 1000, ‘2024-01-10’),
(101, 1500, ‘2024-02-15’),
(102, 2000, ‘2024-01-20’),
(102, 2500, ‘2024-02-25’),
(103, 3000, ‘2024-02-28’);
Теги; #t1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH cte AS (
SELECT
deal_NO,
balance,
report_date,
ROW_NUMBER() OVER(PARTITION BY deal_NO ORDER BY report_date DESC) AS rn
FROM
Deals
)
SELECT
deal_NO, balance, report_date
FROM
cte
WHERE
rn = 1
Ощибся в логике( ГДЕ ФИЛЬТРУЕМ?)
Вывести суммарный баланс по договорам Зарплатный на конец 1 кв. 2018
CREATE TABLE Contracts (
deal_NO INT NOT NULL,
balance DECIMAL(15,2) NOT NULL,
report_date DATE NOT NULL,
contract_type VARCHAR(50) NOT NULL,
PRIMARY KEY (deal_NO, report_date) – Уникальная комбинация
);
INSERT INTO Contracts (deal_NO, balance, report_date, contract_type) VALUES
(201, 5000, ‘2018-03-30’, ‘Зарплатный’),
(201, 5200, ‘2018-03-31’, ‘Зарплатный’),
(202, 3000, ‘2018-03-31’, ‘Зарплатный’),
(203, 4500, ‘2018-02-15’, ‘Зарплатный’),
(204, 4000, ‘2018-03-20’, ‘Зарплатный’),
(205, 6000, ‘2018-03-31’, ‘Кредитный’); – Не учитываем, так как не “Зарплатный”
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH cte AS (
SELECT
*,
ROW_NUMBER() OVER(PARTITION BY deal_NO ORDER BY report_date DESC) AS rn
FROM
Contracts
WHERE
report_date <= ‘2018-03-31’ AND contract_type = ‘Зарплатный’
)
SELECT
SUM(balance) AS total_balance
FROM
cte
WHERE
rn = 1
какая разница в выводе строк между запросами,надо было написать сами запросы и порассуждать
Табл1 Табл2
id id product
1 1 ипотека
2 2
3 3
select table2.product,
from table1 left join table2 on table1.id=table2.id AND table2.product=’Ипотека’
select table2.product,
from table1 left join table2 on table1.id=table2.id
where table2.product=’Ипотека’
теги #t1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Результат запроса 1
product
ипотека
(NULL)
(NULL)
Логика работы:
Выполняется LEFT JOIN таблицы table1 с table2 по id, но с дополнительным условием table2.product = 'Ипотека' в ON. Это означает, что строка из table1 соединится с table2, только если product = 'Ипотека'. Если product не соответствует этому условию или в table2 нет соответствующего id, то для table2.product в результате будет NULL.
Результат запроса 2
product
ипотека
Логика работы:
Сначала выполняется LEFT JOIN, который присоединяет table2 к table1 по id (без фильтрации product на этом этапе). Затем уже на уровне WHERE отфильтровываются только те строки, где table2.product = 'Ипотека'. Если в table2.product NULL, строка будет исключена WHERE-фильтром.
Не решил. забыл логику
таблица со временем, надо найти пересечения (1 решение – ток с друг другом ) (второе – все)
ID Date_start Date_end
1 11 13
2 13 14
3 15 16
CREATE TABLE TimeRanges (
ID SERIAL PRIMARY KEY,
Date_start INT NOT NULL,
Date_end INT NOT NULL CHECK (Date_end > Date_start)
);
INSERT INTO TimeRanges (Date_start, Date_end) VALUES
(11, 13),
(13, 14),
(15, 16);
теги #t1
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
все (даже сам с собой)
SELECT *
FROM TimeRanges t1
JOIN TimeRanges t2
ON t2.Date_end BETWEEN t1.Date_start AND t1.Date_end
ток с друг другом
SELECT *
FROM TimeRanges t1
JOIN TimeRanges t2
ON t1.ID <> t2.ID
AND t1.Date_start <= t2.Date_end
AND t1.Date_end >= t2.Date_start;
решил но невнимательность.
Дана таблица org с полями
name - наименование организации
volume_sales - объем продаж, шт.
Необходимо написать запрос который возвращает список организаций, с указанием объема продаж, состоящий из топ 5 организаций
по объему продаж (от большего к меньшему) + одна строка с объемом продаж организаций не попавших в топ 5.
CREATE TABLE org (
name TEXT,
volume_sales INT
);
INSERT INTO org (name, volume_sales) VALUES
(‘Компания А’, 1000),
(‘Компания B’, 800),
(‘Компания C’, 750),
(‘Компания D’, 600),
(‘Компания E’, 500),
(‘Компания D’, 400),
(‘Компания А’, 350),
(‘Компания D’, 900),
(‘Компания R’, 100),
(‘Компания R’, 100),
(‘Компания Z’, 700),
(‘Компания C’, 300);
теги #Ретейлдата
не решил
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH ranked_orgs AS (
SELECT name, SUM(volume_sales) AS total_sales
FROM org
GROUP BY name
), top_orgs AS (
SELECT name, total_sales
FROM ranked_orgs
ORDER BY total_sales DESC
LIMIT 5
), others AS (
SELECT ‘Остальные’ AS name, COALESCE(SUM(total_sales), 0) AS total_sales
FROM ranked_orgs
WHERE name NOT IN (SELECT name FROM top_orgs)
)
SELECT * FROM top_orgs
UNION ALL
SELECT * FROM others
ORDER BY total_sales DESC;
не решил . сложно
Дана таблица “Календарь” с полями
date - дата
wow - признак выходного или рабочего дня
Написать запрос, который будет возвращать исходную таблицу + колонку с ближайшим следующим рабочим днем, если текущий день выходной.
Календарь
date wow
2018-07-13 Р
2018-07-14 В
2018-07-15 В
2018-07-16 Р
2018-07-17 Р
2018-07-18 Р
2018-07-19 Р
2018-07-20 Р
2018-07-21 В
2018-07-22 В
2018-07-23 Р
2018-07-24 Р\
пример результата
date wow new_date
2018-07-13 Р 2018-07-13
2018-07-14 В 2018-07-16
2018-07-15 В 2018-07-16
2018-07-16 Р 2018-07-16
CREATE TABLE calendar (
date DATE PRIMARY KEY,
wow CHAR(1) CHECK (wow IN (‘Р’, ‘В’))
);
INSERT INTO calendar (date, wow) VALUES
(‘2018-07-13’, ‘Р’),
(‘2018-07-14’, ‘В’),
(‘2018-07-15’, ‘В’),
(‘2018-07-16’, ‘Р’),
(‘2018-07-17’, ‘Р’),
(‘2018-07-18’, ‘Р’),
(‘2018-07-19’, ‘Р’),
(‘2018-07-20’, ‘Р’),
(‘2018-07-21’, ‘В’),
(‘2018-07-22’, ‘В’),
(‘2018-07-23’, ‘Р’),
(‘2018-07-24’, ‘Р’);
теги #Ретейлдата
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
SELECT
date,
wow,
CASE
WHEN wow = ‘В’ THEN (
MIN(date) FILTER (WHERE wow = ‘Р’)
OVER (ORDER BY date ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
)
ELSE NULL
END AS next
FROM calendar;
**не решил дважды. сложно забыл как сессии делать и забыл в коцне **
Представим таблицу событий пользователей в системе. Каждая запись в таблице содержит идентификатор пользователя, метку времени события и тип события.
– Создание таблицы
CREATE TABLE public.events (
user_id INT,
event_ts TIMESTAMP,
event TEXT
);
– Вставка тестовых данных
INSERT INTO public.events (user_id, event_ts, event) VALUES
(1, ‘2023-01-01 12:00:00’, ‘login’),
(1, ‘2023-01-01 12:05:00’, ‘view_page’),
(1, ‘2023-01-01 12:30:00’, ‘logout’),
(2, ‘2023-01-01 13:00:00’, ‘login’),
(2, ‘2023-01-01 13:13:00’, ‘view_page’),
(2, ‘2023-01-01 13:25:00’, ‘purchase’),
(3, ‘2023-01-02 08:00:00’, ‘login’),
(3, ‘2023-01-02 08:45:00’, ‘view_page’),
(3, ‘2023-01-02 08:50:00’, ‘logout’),
(4, ‘2023-01-02 09:00:00’, ‘login’),
(4, ‘2023-01-02 09:10:00’, ‘view_page’),
(4, ‘2023-01-02 09:11:00’, ‘purchase’),
(4, ‘2023-01-02 09:25:00’, ‘logout’),
(5, ‘2023-01-03 10:05:00’, ‘login’),
(5, ‘2023-01-03 10:10:00’, ‘view_page’),
(5, ‘2023-01-03 10:20:00’, ‘view_page’),
(5, ‘2023-01-03 10:40:00’, ‘logout’),
(6, ‘2023-01-03 11:00:00’, ‘login’),
(6, ‘2023-01-03 11:05:00’, ‘view_page’),
(6, ‘2023-01-03 11:30:00’, ‘purchase’),
(6, ‘2023-01-03 11:45:00’, ‘logout’),
(7, ‘2023-01-04 14:00:00’, ‘login’),
(7, ‘2023-01-04 14:10:00’, ‘add_to_cart’),
(7, ‘2023-01-04 14:15:00’, ‘purchase’),
(7, ‘2023-01-04 14:25:00’, ‘logout’),
(8, ‘2023-01-05 16:00:00’, ‘login’),
(8, ‘2023-01-05 16:15:00’, ‘view_page’),
(8, ‘2023-01-05 16:30:00’, ‘view_page’),
(8, ‘2023-01-05 16:50:00’, ‘logout’);
/*
user_id event_ts event
1 2023-01-01 12:00:00 login
1 2023-01-01 12:05:00 view_page
1 2023-01-01 12:30:00 logout
2 2023-01-01 13:00:00 login
2 2023-01-01 13:13:00 view_page
2 2023-01-01 13:25:00 purchase
/
– 1) Наша задача — агрегировать эти события в ‘сессии’. Сессией будем считать последовательность событий одного пользователя, между которыми не проходит более 15 минут. Нужно определить начало и конец каждой сессии. То есть результат должен получиться :
/
user_id session_start session_end
1 2023-01-01 12:00:00 2023-01-01 12:05:00
1 2023-01-01 12:30:00 2023-01-01 12:30:00
2 2023-01-01 13:00:00 2023-01-01 13:25:00
*/
– 2) добавить список событий сессии (события должны быть упорядочены)
/*
user_id,session_start session_end events
1 2023-01-01 12:00:00 2023-01-01 12:05:00 [login, view_page]
1 2023-01-01 12:30:00 2023-01-01 12:30:00 [logout]
2 2023-01-01 13:00:00 2023-01-01 13:25:00 [login,view_page, purchase]
*/
Теги wildberries
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH sessionisation AS (
SELECT
user_id,
event_ts,
event,
CASE
WHEN EXTRACT(EPOCH FROM (event_ts - LAG(event_ts)
OVER (PARTITION BY user_id ORDER BY event_ts))) > 900
OR LAG(event_ts) OVER (PARTITION BY user_id ORDER BY event_ts) IS NULL
THEN 1
ELSE 0
END AS flag
FROM public.events
),
ses_grouping AS (
SELECT
user_id,
event_ts,
event,
SUM(flag) OVER (PARTITION BY user_id ORDER BY event_ts) AS group_flag
FROM sessionisation
)
SELECT
user_id,
MIN(event_ts) AS session_start,
MAX(event_ts) AS session_end,
– Собираем упорядоченный массив событий
array_agg(event ORDER BY event_ts) AS events
FROM ses_grouping
GROUP BY
user_id,
group_flag
ORDER BY
user_id,
session_start;
Дана таблица t, в ней одно поле value. нужно вывести все дубли.
CREATE TABLE t (
value INT
);
INSERT INTO t (value) VALUES
(1), (1), (1), (2), (3), (4), (5), (5), (6), (1), (5);
Теги #ЛигаЦифровогоИнтернета
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
без повторов
SELECT value
FROM t
GROUP BY value
HAVING COUNT(*) > 1;
с повторовов
WITH dup AS (
SELECT
value
FROM
t
GROUP BY
value
HAVING COUNT(*) > 1
)
SELECT
value
FROM
t
WHERE
value IN (SELECT value FROM dup)
Решил. Но что делать в случае если сотрудник один?
Вывести сотрудника и департамент со второй максимальной зарплатой в каждом департаменте за парель 2023 года.
CREATE TABLE employees (
employee_id INT,
department_id INT,
salary NUMERIC,
salary_date DATE
);
INSERT INTO employees (employee_id, department_id, salary, salary_date) VALUES
(1, 101, 50000, ‘2023-04-01’),
(2, 101, 70000, ‘2023-04-01’),
(3, 101, 80000, ‘2023-04-01’),
(4, 102, 55000, ‘2023-04-01’),
(5, 102, 75000, ‘2023-04-01’),
(6, 102, 85000, ‘2023-04-01’),
(7, 103, 60000, ‘2023-04-01’),
(8, 103, 72000, ‘2023-04-01’),
(9, 103, 88000, ‘2023-04-01’);
Теги #ЛигаЦифровогоИнтернета
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH cte AS (
SELECT
employee_id, department_id, salary, salary_date,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rn
FROM
employees
)
SELECT
employee_id, department_id, salary, salary_date
FROM
cte
WHERE rn = 2
**Не решил **
Есть две таблицы с приходами и списаниями с банковских счетов:
Income
account_id datetime amount
Outcome
account_id datetime amount
Необходимо написать запрос, который вернет баланс выбранного счета на каждый день когда были операции выбранного месяца. (в рамках задачи id только 777 и месяц февраль 2024
CREATE TABLE income (
account_id INT,
datetime TIMESTAMP,
amount NUMERIC
);
INSERT INTO income (account_id, datetime, amount) VALUES
(777, ‘2024-02-01 10:00:00’, 1000),
(777, ‘2024-02-05 14:00:00’, 500),
(777, ‘2024-02-10 16:30:00’, 2000),
(555, ‘2024-02-02 09:00:00’, 300), – другой счет
(777, ‘2024-03-01 12:00:00’, 400), – другой месяц
(888, ‘2024-02-10 15:00:00’, 600); – другой счет
CREATE TABLE outcome (
account_id INT,
datetime TIMESTAMP,
amount NUMERIC
);
INSERT INTO outcome (account_id, datetime, amount) VALUES
(777, ‘2024-02-03 11:00:00’, 300),
(777, ‘2024-02-07 12:45:00’, 700),
(777, ‘2024-02-12 18:15:00’, 1500),
(555, ‘2024-02-04 08:30:00’, 200), – другой счет
(777, ‘2024-03-02 17:00:00’, 500), – другой месяц
(888, ‘2024-02-15 10:30:00’, 900); – другой счет
Теги #ЛигаЦифровогоИнтернета
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
WITH all_transactions AS (
SELECT account_id, datetime, amount, ‘income’ AS source
FROM income
WHERE account_id = 777 AND DATE_TRUNC(‘month’, datetime) = ‘2024-02-01’
UNION ALL SELECT account_id, datetime, amount, 'outcome' AS source FROM outcome WHERE account_id = 777 AND DATE_TRUNC('month', datetime) = '2024-02-01' )
SELECT
datetime,
EXTRACT(MONTH FROM datetime) AS month,
EXTRACT(DAY FROM datetime) AS day,
SUM(CASE WHEN source = ‘income’ THEN amount ELSE -amount END)
OVER (ORDER BY datetime) AS balance
FROM all_transactions
ORDER BY datetime, month, day
не решил
Список сотрудников, которые старше своего непосредственного руководителя
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name TEXT,
birth_date DATE,
manager_id INT
);
INSERT INTO employees (employee_id, name, birth_date, manager_id) VALUES
(1, ‘Иван Иванов’, ‘1985-06-15’, NULL), – Руководитель
(2, ‘Петр Петров’, ‘1990-04-20’, 1), – Подчиненный
(3, ‘Анна Смирнова’, ‘1983-09-10’, 1), – Подчиненный старше руководителя
(4, ‘Олег Сидоров’, ‘1995-07-25’, 2), – Подчиненный
(5, ‘Мария Кузнецова’, ‘1987-12-05’, 2);– Подчиненный
Теги #т-банк
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ
Ответ