Во-первых, вам нужно сделать календарь на весь год или на целый месяц, поэтому я бы использовал cte recursion , чтобы сделать это.
SELECT DATEADD(month, DATEDIFF(month, 0, getdate()), 0) AS StartOfMonth,
DATEADD(mm,1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)) - 1 AS EndOfMonth
UNION ALL
SELECT StartOfMonth +1 , EndOfMonth
FROM CTE
WHERE StartOfMonth < EndOfMonth
есть 7 дней в неделю, что бы ни начиналось с любой недели, тогда мы увидим эту проблему Пробелы и острова , потому что номер недели будет повторяться от 1
до 7
.
Так что я бы использовал CASE WHEN
с DateName to make your customer week date number, which number starts on
Friday` или в зависимости от вашей логики.
;WITH CTE AS (
SELECT DATEADD(month, DATEDIFF(month, 0, getdate()), 0) AS StartOfMonth,
DATEADD(mm,1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)) - 1 AS EndOfMonth
UNION ALL
SELECT StartOfMonth +1 , EndOfMonth
FROM CTE
WHERE StartOfMonth < EndOfMonth
)
SELECT *,
CASE DateName(DW, StartOfMonth)
WHEN 'Friday' THEN 0
WHEN 'Saturday' THEN 1
WHEN 'Sunday' THEN 2
WHEN 'Monday' THEN 3
WHEN 'Tuesday' THEN 4
WHEN 'Wednesday' THEN 5
WHEN 'Thursday' THEN 6
WHEN 'Tuesday' THEN 7
END grp,
ROW_NUMBER() OVER(ORDER BY StartOfMonth) rn
FROM CTE
[Результаты]
| StartOfMonth | EndOfMonth | grp | rn |
|----------------------|----------------------|-----|----|
| 2018-09-01T00:00:00Z | 2018-09-30T00:00:00Z | 1 | 1 |
| 2018-09-02T00:00:00Z | 2018-09-30T00:00:00Z | 2 | 2 |
| 2018-09-03T00:00:00Z | 2018-09-30T00:00:00Z | 3 | 3 |
| 2018-09-04T00:00:00Z | 2018-09-30T00:00:00Z | 4 | 4 |
| 2018-09-05T00:00:00Z | 2018-09-30T00:00:00Z | 5 | 5 |
| 2018-09-06T00:00:00Z | 2018-09-30T00:00:00Z | 6 | 6 |
| 2018-09-07T00:00:00Z | 2018-09-30T00:00:00Z | 0 | 7 |
| 2018-09-08T00:00:00Z | 2018-09-30T00:00:00Z | 1 | 8 |
| 2018-09-09T00:00:00Z | 2018-09-30T00:00:00Z | 2 | 9 |
| 2018-09-10T00:00:00Z | 2018-09-30T00:00:00Z | 3 | 10 |
| 2018-09-11T00:00:00Z | 2018-09-30T00:00:00Z | 4 | 11 |
| 2018-09-12T00:00:00Z | 2018-09-30T00:00:00Z | 5 | 12 |
| 2018-09-13T00:00:00Z | 2018-09-30T00:00:00Z | 6 | 13 |
| 2018-09-14T00:00:00Z | 2018-09-30T00:00:00Z | 0 | 14 |
| 2018-09-15T00:00:00Z | 2018-09-30T00:00:00Z | 1 | 15 |
| 2018-09-16T00:00:00Z | 2018-09-30T00:00:00Z | 2 | 16 |
| 2018-09-17T00:00:00Z | 2018-09-30T00:00:00Z | 3 | 17 |
| 2018-09-18T00:00:00Z | 2018-09-30T00:00:00Z | 4 | 18 |
| 2018-09-19T00:00:00Z | 2018-09-30T00:00:00Z | 5 | 19 |
| 2018-09-20T00:00:00Z | 2018-09-30T00:00:00Z | 6 | 20 |
| 2018-09-21T00:00:00Z | 2018-09-30T00:00:00Z | 0 | 21 |
| 2018-09-22T00:00:00Z | 2018-09-30T00:00:00Z | 1 | 22 |
| 2018-09-23T00:00:00Z | 2018-09-30T00:00:00Z | 2 | 23 |
| 2018-09-24T00:00:00Z | 2018-09-30T00:00:00Z | 3 | 24 |
| 2018-09-25T00:00:00Z | 2018-09-30T00:00:00Z | 4 | 25 |
| 2018-09-26T00:00:00Z | 2018-09-30T00:00:00Z | 5 | 26 |
| 2018-09-27T00:00:00Z | 2018-09-30T00:00:00Z | 6 | 27 |
| 2018-09-28T00:00:00Z | 2018-09-30T00:00:00Z | 0 | 28 |
| 2018-09-29T00:00:00Z | 2018-09-30T00:00:00Z | 1 | 29 |
| 2018-09-30T00:00:00Z | 2018-09-30T00:00:00Z | 2 | 30 |
тогда мы можем попытаться использовать rn - grp
, чтобы получить группу, которая является непрерывной.
[Результаты]
| StartOfMonth | EndOfMonth | grp |
|----------------------|----------------------|-----|
| 2018-09-01T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-02T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-03T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-04T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-05T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-06T00:00:00Z | 2018-09-30T00:00:00Z | 0 |
| 2018-09-07T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-08T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-09T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-10T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-11T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-12T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-13T00:00:00Z | 2018-09-30T00:00:00Z | 7 |
| 2018-09-14T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-15T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-16T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-17T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-18T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-19T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-20T00:00:00Z | 2018-09-30T00:00:00Z | 14 |
| 2018-09-21T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-22T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-23T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-24T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-25T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-26T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-27T00:00:00Z | 2018-09-30T00:00:00Z | 21 |
| 2018-09-28T00:00:00Z | 2018-09-30T00:00:00Z | 28 |
| 2018-09-29T00:00:00Z | 2018-09-30T00:00:00Z | 28 |
| 2018-09-30T00:00:00Z | 2018-09-30T00:00:00Z | 28 |
final, мы просто получаем все count(*) = 7
группы по месяцам или годам, что означает полные недели.
Запрос 1 :
полный месяц
;WITH CTE AS (
SELECT DATEADD(month, DATEDIFF(month, 0, getdate()), 0) AS StartOfMonth,
DATEADD(mm,1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)) - 1 AS EndOfMonth
UNION ALL
SELECT StartOfMonth +1 , EndOfMonth
FROM CTE
WHERE StartOfMonth < EndOfMonth
)
SELECT COUNT(*) fullweekAmount from (
SELECT
MIN(StartOfMonth) startdt,
MAX(StartOfMonth) enddt
FROM (
SELECT *,
ROW_NUMBER() OVER(ORDER BY StartOfMonth) -
CASE DateName(DW, StartOfMonth)
WHEN 'Friday' THEN 0
WHEN 'Saturday' THEN 1
WHEN 'Sunday' THEN 2
WHEN 'Monday' THEN 3
WHEN 'Tuesday' THEN 4
WHEN 'Wednesday' THEN 5
WHEN 'Thursday' THEN 6
WHEN 'Tuesday' THEN 7
END grp
FROM CTE
) t1
GROUP BY grp
having count(*) = 7
) t1
Результаты
| fullweekAmount |
|----------------|
| 3 |
полный год
;WITH CTE AS (
SELECT DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AS StartOfMonth,
DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1) - 1 AS EndOfMonth
UNION ALL
SELECT StartOfMonth +1 , EndOfMonth
FROM CTE
WHERE StartOfMonth < EndOfMonth
)
SELECT COUNT(*) fullweekAmount from (
SELECT
MIN(StartOfMonth) startdt,
MAX(StartOfMonth) enddt
FROM (
SELECT *,
ROW_NUMBER() OVER(ORDER BY StartOfMonth) -
CASE DateName(DW, StartOfMonth)
WHEN 'Friday' THEN 0
WHEN 'Saturday' THEN 1
WHEN 'Sunday' THEN 2
WHEN 'Monday' THEN 3
WHEN 'Tuesday' THEN 4
WHEN 'Wednesday' THEN 5
WHEN 'Thursday' THEN 6
WHEN 'Tuesday' THEN 7
END grp
FROM CTE
) t1
GROUP BY grp
having count(*) = 7
) t1
option (maxrecursion 0)
sqlfiddle
Примечание
если ваша cte recursion дата больше 100, вы получите ошибку
Заявление прекращено. Максимальная рекурсия 100 была исчерпана до завершения оператора.
вы можете установить
option (maxrecursion 0)
Case When
число 0
и 1
означают ваш выходной день