Skip to content

Instantly share code, notes, and snippets.

@ShutovAndrey
Created October 18, 2022 08:56
Show Gist options
  • Save ShutovAndrey/fc2b0d5ac155da253c89302baf46af77 to your computer and use it in GitHub Desktop.
Save ShutovAndrey/fc2b0d5ac155da253c89302baf46af77 to your computer and use it in GitHub Desktop.
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