Created
October 18, 2022 08:56
-
-
Save ShutovAndrey/fc2b0d5ac155da253c89302baf46af77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I. | |
1) Выборки пользователей, у которых количество постов больше, чем у пользователя их пригласившего. | |
SELECT u1.* | |
FROM users u1 | |
WHERE u1.posts_qty > | |
(SELECT posts_qty | |
FROM users u2 | |
WHERE u2.id = u1.invited_by_user_id); | |
2)Выборки пользователей, имеющих максимальное количество постов в своей группе. | |
#сортируем и берем первый элемент | |
WITH ranked AS | |
(SELECT u.id, | |
ROW_NUMBER() | |
OVER (PARTITION BY group_id | |
ORDER BY posts_qty desc) AS rn | |
FROM users AS u ) | |
SELECT id | |
FROM ranked | |
WHERE rn = 1; | |
3) Выборки групп, количество пользователей в которых превышает 10000. | |
SELECT group_id | |
FROM users | |
GROUP BY group_id | |
HAVING count(id) > 10000; | |
4) Выборки пользователей, у которых пригласивший их пользователь из другой группы. | |
SELECT u1.* | |
FROM users1 u1 | |
WHERE u1.group_id NOT IN | |
(SELECT group_id | |
FROM users1 u2 | |
WHERE u2.id = u1.invited_by_user_id); | |
5) Выборки групп с максимальным количеством постов у пользователей. | |
#лимит регулирует количество групп с максимальным количеством постов | |
WITH ranked AS | |
(SELECT DISTINCT group_id, | |
sum(posts_qty) | |
OVER (PARTITION BY group_id) AS sum | |
FROM users1 | |
ORDER BY sum DESC ) | |
SELECT group_id | |
FROM ranked limit 2; | |
II. | |
#возьмем пример из предыдущего блока | |
#создадим таблицу с необходимой структурой(с изменениями) и будем переливать в нее данные из старой таблицы | |
create table users_new | |
( | |
id int not null primary key auto_increment, | |
group_id int not null, | |
invited_by_user int not null, | |
name varchar(70) not null, | |
posts_qty int, | |
last_name varchar(70) default '', | |
address varchar(70) default '', | |
city varchar(70) default '', | |
constraint fk_users_new_group_id | |
foreign key (group_id) references `groups` (id) | |
on update cascade on delete cascade | |
); | |
create index index_name on users_new (name); | |
create index index_city on users_new (city); | |
#тригер на update если уже записалось в таблицу, если нет - запишется уже с обновлениями | |
drop trigger if EXISTS update_users_new; | |
delimiter $$ | |
create trigger update_users_new after update on users | |
for each row | |
begin | |
if exists (select id from users_new where id = new.id) then | |
update users_new SET | |
group_id=new.group_id, | |
invited_by_user=new.invited_by_user_id, | |
name=new.name, | |
posts_qty=new.posts_qty | |
where id=new.id; | |
end if; | |
end$$ | |
delimiter ; | |
insert into users_new (id, group_id, invited_by_user, name, posts_qty) | |
select id, | |
group_id, | |
invited_by_user_id, | |
name, | |
posts_qty | |
from users; | |
rename table users to __users, users_new to users; | |
drop trigger update_users_new; | |
III. | |
<?php | |
const TUESDAY = 2; | |
const WEEK = 7; | |
/** | |
* Collect data from user and return it if it's valid | |
* @return array|bool | |
*/ | |
function getDatesFromUser(): ?array | |
{ | |
$format = 'Y-m-d'; | |
$days = ['first', 'second']; | |
$resultDates = []; | |
foreach ($days as $day) { | |
$dateFromUser = readline("Enter {$day} date in format {$format}: "); | |
$date = DateTime::createFromFormat($format, $dateFromUser); | |
if ($date && $date->format($format) == $dateFromUser) { | |
array_push($resultDates, $date); | |
} else { | |
$resultDates = null; | |
break; | |
} | |
} | |
return $resultDates; | |
} | |
if (!list($start, $end) = getDatesFromUser()) { | |
echo ('Invalid date' . PHP_EOL); | |
return; | |
} | |
$diffDays = (int)$start->diff($end)->format("%a"); | |
$start = (int)$start->format('w'); | |
$end = (int)$end->format('w'); | |
//start day can be a tuesday so we check cout of weeks in diff days + start | |
$tuesdays = intdiv(($start + $diffDays), WEEK); | |
//second date also could be a tuesday, so we need to chek it iff diff is less than a week | |
if ($diffDays < WEEK) { | |
if ($end == TUESDAY) { | |
$tuesdays += 1; | |
} | |
} | |
echo 'Tuesdays count is ' . $tuesdays . PHP_EOL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment