Вы можете решить, в какую половину месяца выпадает дата, используя функцию day
, и переходите соответственно, используя функцию iif
, например:
iif(day(wkd)<16, <first half of month>, <second half of month>)
Затем вам нужно вычислить соответствующие даты, соответствующие <first half of month>
и <second half of month>
в вышеприведенном выражении.
Для этого я бы лично использовал dateserial
function.
Конец первой половины месяца (т. е. 15-го дня) можно рассчитать, используя:
dateserial(year(wkd), month(wkd), 15)
Конец второй половины месяца (т. е. последнего днямесяца) можно рассчитать, используя:
dateserial(year(wkd), month(wkd)+1, 0)
То есть день 0 th следующего месяца.Функция dateserial
очень полезна тем, что она всегда будет вычислять действительную дату из предоставленных параметров - следовательно, если year(wkd) = 2019
& month(wkd)+1 = 13
, то вместо возврата ошибки, поскольку номер месяцабольше 12, dateserial(2019, 13, 0)
вернет 31 декабря 2019 года, как и ожидалось.
Собрав все вместе, у нас есть поле FortnightEnding
:
iif
(
day(wkd)<16,
dateserial(year(wkd),month(wkd),15),
dateserial(year(wkd),month(wkd)+1,0)
) as FortnightEnding
И поэтому мы можем построитьследующий SQL:
select
empid,
iif
(
day(wkd)<16,
dateserial(year(wkd),month(wkd),15),
dateserial(year(wkd),month(wkd)+1,0)
) as FortnightEnding,
sum(gross)
from
tblpayroll
group by
empid,
iif
(
day(wkd)<16,
dateserial(year(wkd),month(wkd),15),
dateserial(year(wkd),month(wkd)+1,0)
)
Группировка по одному и тому же вычислению приводит к суммированию поля gross
для всех дат, попадающих в каждую группу.
Если вы не хотите повторятьВ операторе вычисления можно вычислить группировку в подзапросе и агрегировать результаты в родительском запросе, например:
select t.empid, t.FortnightEnding, sum(t.gross)
from
(
select
empid,
iif
(
day(wkd)<16,
dateserial(year(wkd),month(wkd),15),
dateserial(year(wkd),month(wkd)+1,0)
) as FortnightEnding,
gross
from
tblpayroll
) t
group by t.empid, t.FortnightEnding