T- SQL Скрипт для подсчета дня - PullRequest
0 голосов
/ 15 января 2020

Я создал таблицу с этой строкой данных:

WorkerID  StartDate  EndDate
========  =========  ==========
0001      2019/11/1  2019/11/2

Когда я пишу день, отличный для рабочего 0001 в ноябре / 2019, это довольно просто:

SELECT WorkerID, [WorkingDay]= DATEDIFF(day, [EndDate], [StartDate]) 
where [StartDate ] >= '2019-11-1' and EndDate <='2019-11-30'

однако, если запись такова:

WorkerID  StartDate   EndDate
========  =========   ==========
0001      2019/11/29  2019/12/3

, мне понадобится таблица результатов, как показано ниже

WorkerID  Workday     WorkFirstDayOfMonth
========  =========   ===================
0001      2            2019/11/1
0001      3            2019/12/1

Могу ли я узнать, как написать запрос T- SQL? Соответствующее предложение where

where [StartDate ] >= '2019-11-1' and EndDate <='2019-12-31'

1 Ответ

0 голосов
/ 15 января 2020

Я думаю, что вы, вероятно, захотите настоящую таблицу календаря, чтобы вы могли учитывать выходные и праздничные дни. Но это вернет результаты, которые вы ищете. Я сделал это достаточно гибким, чтобы работать в течение нескольких месяцев. Я использую cte в качестве таблицы подсчета, которая делает недолгой работу такого рода вещей. Обратите внимание, что я добавил вторую строку для WorkerID xxxx с несколькими месяцами.

declare @Something table
(
    WorkerID char(4)
    , StartDate date
    , EndDate date
)

insert @Something values
('0001', '20191129', '20191203')
, ('xxxx', '20190929', '20191203')
;

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a cross join E1 b), 
    InlineTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2
    )

select WorkerID
    , StartDate
    , EndDate
    , WorkDay = case when t.N = 1 --the first month
                    then datediff(day, StartDate, dateadd(month, datediff(month, 0, StartDate) + 1, 0)) 
                when datepart(month, dateadd(month, t.N - 1, StartDate)) < datepart(month, EndDate) --not the first OR the last month
                    then datediff(day, dateadd(month, datediff(month, t.N - 1, dateadd(month, t.N - 1, StartDate)), 0), dateadd(month, datediff(month, 0, dateadd(month, t.N - 1, StartDate)) + 1, 0))
                else --the last month
                    datediff(day, dateadd(month, datediff(month, 0, EndDate), 0), EndDate) + 1  
                end
    , FirstDayOfMonth = convert(date, dateadd(month, datediff(month, t.N - 1, dateadd(month, t.N - 1, StartDate)), 0))
from @Something s
join InlineTally t on t.N <= datediff(month, StartDate, EndDate) + 1
order by s.WorkerID
    , t.N

Возвращает:

WorkerID | StartDate  | EndDate    | WorkDay | FirstDayOfMonth
0001     | 2019-11-29 | 2019-12-03 |2        | 2019-11-01
0001     | 2019-11-29 | 2019-12-03 |3        | 2019-12-01
xxxx     | 2019-09-29 | 2019-12-03 |2        | 2019-09-01
xxxx     | 2019-09-29 | 2019-12-03 |31       | 2019-10-01
xxxx     | 2019-09-29 | 2019-12-03 |30       | 2019-11-01
xxxx     | 2019-09-29 | 2019-12-03 |3        | 2019-12-01
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...