#sql #postgresql #metabase
Вопрос:
На этот раз у меня есть таблица в базе данных PostgreSQL, которая содержит имя сотрудника, дату, когда он начал работать, и дату, когда он покидает компанию, в тех случаях, когда сотрудник все еще остается в компании, это поле имеет нулевое значение. Зная это, я хотел бы знать, сколько людей работало в заранее определенную дату, например:
Я хотел бы знать, сколько человек работает в компании в январе 2021 года.
Я не знаю, с чего начать, в некоторых попытках я получил количество наймов и увольнений в месяц, но мне нужно показать это накопленное значение в месяц в другой колонке.
Надеюсь, я правильно выразился, я оставлю последний SQL, который я получил здесь.
select reference, sum(hires) from
(
select
date_trunc('month', date_hires) as reference,
count(*) as hires
from
ponto_mais_relatorio_colaboradores
group by
date_hires
union all
select
date_trunc('month', date_layoff) as reference,
count(*)*-1 as layoffs
from
ponto_mais_relatorio_colaboradores
group by
date_layoff
) as reference
join calendar_aux on calendar_aux.ano_mes = reference
group by reference
order by reference
Ответ №1:
Разбейте это требование на части. Вопрос: сколько человек занято на любую конкретную дату? Это будет включать всех нанятых до этой даты и не имеющих даты увольнения плюс всех нанятых ранее с датой увольнения позже даты вашего интересующего периода. Т. е. вас интересует январь, поэтому вы все еще хотите посчитать сотрудника с датой увольнения в феврале. С этим на месте преобразуйте в SQL. Предыдущее доступно в разделе «Выбор дат сравнения». другая проблема заключается в том, что январь-это не дата, это диапазон дат, поэтому вам нужна каждая дата. Вы можете использовать генерацию серий для создания каждого дня в январе. Затем соедините сгенерированные даты с выбором из вашей таблицы. Результирующий запрос:
with jan_dates( jdate ) as
( select generate_series( date '2021-01-01'
, date '2021-01-31'
, interval '1' day
)::date
)
select jdate "Date", count(*) "Employees"
from jan_dates j
join employees e
on ( e.date_hires <= j.jdate
and ( e.date_layoff is null
or e.date_layoff > j.jdate
)
)
group by j.jdate
order by j.jdate;
Примечание: Не тестировалось.