SQL
Язык SQL — прекрасная вещь, пожалуй, одна из лучших, что мы имеем в айти. Научиться ему значит повысить свою квалификацию на голову. Бекендеров я бы вообще оценивал по одному критерию — насколько хорошо они работают с базой.
SQL выручал меня не только по работе. У нас в ЖК стоят шлагбаумы, и однажды я запросил логи, чтобы посмотреть, кто и когда и открывает. Мне скинули несколько страшных CSV. Разбирать их Экселе было адом, и я загнал в Постгрес и построил отчеты по всем мыслимым критериям.
Импорт:
COPY logs(time, account, type, ident, status, barrier)
FROM '/Users/ivan/work/barriers/65_Ш6.csv'
DELIMITER ';' CSV HEADER;
Статусы:
select distinct status from logs
| status
|---------------------------------------
| Добавлен
| Отказ (пульт)
| Отказ (нет в базе или ошибка кнопка)
| Открыто (карта в базе)
| Допуск (пульт)
...
Типы доступа:
select distinct type from logs
| type
|--------------
| Событие
| Карта, метка
| Звонок
| Удаление
...
Общее число открываний в разрезе помещений:
select account, count(ident) as count from logs
where account <> 'Нет в базе'
and time > '2022-05-01 00:00:00'
and status in ('Допуск (телефон)', 'Допуск (пульт)')
and type in ('PP', 'Звонок')
group by account
order by count desc
limit 50
Данные по конкретной квартире по дням:
select date_trunc('day', time) as day, count(ident) from logs
where account = 'ООО "Рога и копыта"'
and time > '2022-05-01 00:00:00'
and status in ('Допуск (телефон)', 'Допуск (пульт)')
and type in ('PP', 'Звонок')
group by day
order by day desc
limit 50
Число телефонов и пультов на помещение:
select account, count(distinct ident) as amount from logs
where account <> 'Нет в базе'
and time > '2022-05-01 00:00:00'
and status in ('Допуск (телефон)', 'Допуск (пульт)')
group by account
order by amount desc
limit 100
Среднее число открываний в день:
select account, count(ident) / count(distinct date_trunc('day', time)) as per_day
from logs
where account <> 'Нет в базе'
and time > '2022-05-01 00:00:00'
and status in ('Допуск (телефон)', 'Допуск (пульт)')
and type in ('PP', 'Звонок')
group by account
order by per_day desc
limit 100
И еще штук десять подобных запросов. В итоге нашли несколько аномалий, с нарушителями был разговор.
Из недавнего: понадобилось считать рабочие часы по неделям. Что в Экселе, что
Гугле это оказался адский ад, потому что тип time
не переполняется. То есть если
сложить 7 + 7 + 7 + 7 + 7 часов (пять рабочих дней), получим 11 часов, потому что 24
уйдут в перекрут. Просидел час, думая, как это решить, и так и не решил.
Но выручил Постгрес! Его тип time
тоже не поддерживает переполнение, но есть
тип interval
, который прекрасно складывается сам с собой. Поэтому создаем
таблицу с двумя колонками: дата и интервал:
create table work (date date, hours interval);
Импорт:
\copy work from /Users/ivan/Downloads/foobar.csv
with (format csv);
Удаляем пустые интервалы:
delete from work where hours is null;
Всего часов:
select sum(hours) from work;
Отчет по неделям:
select date_trunc('week', date) as week, sum(hours)
from work
group by week
order by week;
И все это — не выходя из консоли psql
. Представьте, какой гемор был бы
построить это в Экселе, Гугле или даже на языке программирования вроде
Питона. Там с одним только парсингом дат и времени наешься, а тут все из
коробки.
Можно сбросить все отчеты в CSV одной командой, чтобы пересохранить в Excel и отправить кому-то по работе.
Словом, одно из немногих утешений сегодня — это SQL/Postgres. Надежный как скала, полезный, простой и востребованный.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter