Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions 6th hometask/1th task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
-- 2. Пусть задан некоторый пользователь.
-- Из всех друзей этого пользователя найдите человека, который больше всех общался с нашим пользователем.

-- Переменная для хранения id некоторого пользователя, друзей которого нужно найти.
SET @USER_ID := 6;

SELECT
-- Так как запрос дружбы может быть либо создан самим пользователем, либо принят от другого пользователя,
-- необходимо определить id друзей пользователя, которые отличны от id самого пользователя.
IF(f.user_id = @USER_ID, f.target_user_id, f.user_id) AS user_friend_id,
(
SELECT COUNT(m.text)
FROM message AS m
WHERE
-- Среди всех сообщений нужно найти те, где искомый пользователь был либо отправителем, либо получателем сообщений.
(m.from_user_id = @USER_ID OR m.to_user_id = @USER_ID)
AND
-- Для сопоставления строк нужно использовать id друзей пользователя, а не id самого пользователя.
IF(m.from_user_id = @USER_ID, m.to_user_id, m.from_user_id) = IF(f.user_id = @USER_ID, f.target_user_id, f.user_id)
) AS amount_of_messages
FROM friend_request AS f
WHERE
f.status = 1
AND
(f.user_id = @USER_ID OR f.target_user_id = @USER_ID)
-- Сортировка пользователей по убыванию кол-ва их сообщений
ORDER BY amount_of_messages DESC
LIMIT 1;

-- Решение с использованием JOIN

SELECT
IF(fr.user_id = @USER_ID, fr.target_user_id, fr.user_id) AS user_friend_id,
COUNT(*) AS amount_of_messages
FROM friend_request AS fr
INNER JOIN message AS m
ON (m.from_user_id = fr.user_id AND m.to_user_id = fr.target_user_id)
OR (m.to_user_id = fr.user_id AND m.from_user_id = fr.target_user_id)
WHERE
(fr.user_id = @USER_ID OR fr.target_user_id = @USER_ID)
AND
fr.status = 1
GROUP BY IF(fr.user_id = @USER_ID, fr.target_user_id, fr.user_id)
ORDER BY amount_of_messages DESC
LIMIT 1;
26 changes: 26 additions & 0 deletions 6th hometask/2th task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-- 3. Подсчитать общее количество лайков, которые получили 10 самых молодых пользователей.

-- CTE для формирования списка id самых молодых пользователей.
WITH t1 AS (
SELECT p.user_id
FROM profile AS p
-- Сортировка пользователей по возрастанию их возраста
ORDER BY p.birth_date DESC
LIMIT 10
)

SELECT COUNT(*) AS total_amount_of_likes
FROM like_user AS lu
WHERE lu.target_user_id IN (SELECT * FROM t1);

-- Решение с использованием JOIN

SELECT COUNT(t1.target_user_id) AS total_amount_likes
FROM (
SELECT
DENSE_RANK() OVER(ORDER BY p.birth_date DESC) AS dr,
lu.target_user_id
FROM profile AS p
LEFT JOIN like_user AS lu ON lu.target_user_id = p.user_id
) AS t1
WHERE t1.dr <= 10;
42 changes: 42 additions & 0 deletions 6th hometask/3th task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-- 4. Определить кто больше поставил лайков (всего) - мужчины или женщины?

SELECT
(SELECT p.gender FROM profile AS p WHERE p.user_id = total_list_of_likes.user_id) AS gender,
COUNT(total_list_of_likes.user_id) AS total_amount_of_likes
FROM (
-- Поскольку данные о лайках хранятся в разных таблицах,
-- необходимо получить полный список лайков.
SELECT m.user_id
FROM like_media AS m
UNION ALL
SELECT p.user_id
FROM like_post AS p
UNION ALL
SELECT u.user_id
FROM like_user AS u
) total_list_of_likes
GROUP BY
gender
HAVING
-- Без учёта пользователей не указавших пол.
gender <> 'x'
-- Сортировка групп пользователей по убыванию кол-ва их лайков
ORDER BY total_amount_of_likes DESC
LIMIT 1;

-- Решение с использованием JOIN

SELECT
p.gender,
COUNT(DISTINCT p.user_id, lm.media_id) +
COUNT(DISTINCT p.user_id, lp.post_id) +
COUNT(DISTINCT p.user_id, lu.target_user_id)
AS total_amount_of_likes
FROM profile AS p
LEFT JOIN like_media AS lm ON lm.user_id = p.user_id
LEFT JOIN like_post AS lp ON lp.user_id = p.user_id
LEFT JOIN like_user AS lu ON lu.user_id = p.user_id
WHERE p.gender <> 'x'
GROUP BY p.gender
ORDER BY total_amount_of_likes DESC
LIMIT 1;
42 changes: 42 additions & 0 deletions 6th hometask/4th task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
-- 5. Найти 10 пользователей, которые проявляют наименьшую активность в использовании социальной сети.

SELECT
u.id,
-- Оценка степени активности пользователя по кол-ву поставленных лайков, коэффицент = 1
(SELECT COUNT(*) FROM like_media AS m WHERE m.user_id = u.id) * 1 +
(SELECT COUNT(*) FROM like_post AS p WHERE p.user_id = u.id) * 1 +
(SELECT COUNT(*) FROM like_user AS u WHERE u.user_id = u.id) * 1 +
-- Оценка степени активности пользователя по кол-ву отправленных сообщений, коэффицент = 10
(SELECT COUNT(*) FROM message AS me WHERE me.from_user_id = u.id) * 10 +
-- Оценка степени активности пользователя по кол-ву отправленных запросов в друзья, коэффицент = 20
(SELECT COUNT(*) FROM friend_request AS f WHERE f.user_id = u.id) * 20 +
-- Оценка степени активности пользователя по кол-ву принятых запросов в друзья, коэффицент = 10
(SELECT COUNT(*) FROM friend_request AS f WHERE f.target_user_id = u.id AND f.status = 1) * 10 +
-- Оценка степени активности пользователя по кол-ву написанных постов, коэффицент = 50
(SELECT COUNT(*) FROM post AS po WHERE po.user_id = u.id) * 50 AS grade_of_activity
FROM user AS u
-- Сортировка пользователей по возрастанию коэффициента их активности
ORDER BY grade_of_activity ASC
LIMIT 10;

-- Решение с использованием JOIN

SELECT
u.id,
COUNT(DISTINCT lm.user_id, lm.media_id) * 1 +
COUNT(DISTINCT lp.user_id, lp.post_id) * 1 +
COUNT(DISTINCT lu.user_id, lu.target_user_id) * 1 +
COUNT(DISTINCT m.id) * 10 +
COUNT(DISTINCT fr.user_id, fr.target_user_id) * 20 +
COUNT(DISTINCT p.id) * 50
AS grade_of_activity
FROM user AS u
LEFT JOIN like_media AS lm ON lm.user_id = u.id
LEFT JOIN like_post AS lp ON lp.user_id = u.id
LEFT JOIN like_user AS lu ON lu.user_id = u.id
LEFT JOIN message AS m ON m.from_user_id = u.id
LEFT JOIN friend_request AS fr ON fr.user_id = u.id
LEFT JOIN post AS p ON p.user_id = u.id
GROUP BY u.id
ORDER BY grade_of_activity ASC
LIMIT 10;