Преобразование предложения WHERE в выражение CASE - PullRequest
0 голосов
/ 20 сентября 2018

Может кто-нибудь помочь мне переписать это, используя CASE (используя легко читаемый синтаксис):

SELECT *
FROM TBL_A
WHERE COLUMN_A BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, +1, GETDATE()), 0) 
                   AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()), -1)

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Использование case expression в том, где предложение просто не облегчит чтение.Вам нужно будет ознакомиться с обработкой даты в T-SQL, которая включает функции dateadd() и datediff().Кроме того, getdate() - это системная функция, которая возвращает текущую дату и время с сервера.

Попробуйте выполнить это сначала:

select dateadd(day,0,0) [Zero Point of Zero Date in TSQL]

= 1900-01-01 00:00:00+00000

В T-SQL все даты / времяизмерено с 1 января 1900 г., так что select возвращает: потому что мы добавили ноль дней к нулевой дате с помощью этого: dateadd(day,0,0)

Итак, теперь вы знаете, что такое нулевая дата, сравнивая ее с текущей датой& время может быть использовано для расчета других полезных дат, таких как первый день текущего месяца.Попробуйте это:

SELECT DATEDIFF(MONTH, 0, GETDATE()) [Number of Months From Date Zero] 

= 1424

Возвращает целое число, равное количеству месяцев с нуля.В вашем первоначальном запросе он использует +1 вместо нуля, но все равно возвращает то же количество месяцев.

SELECT DATEDIFF(MONTH, +1, GETDATE()) [Number of Months From Date One] 

= 1424

Теперь, если мы добавим 1424 месяца к 1900-01-01 (что является "нулевой датой"") мы получаем интересный результат, это первый день текущего месяца

select DATEADD(MONTH, DATEDIFF(MONTH, +1, GETDATE()), 0)  [1st Day of Current Month]

= 2018-09-01 00:00:00+00000

Теперь запустим следующую интересную дату:

select DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()), -1) [Last Day of Current Month]

= 2018-09-30 00:00:00+00000

Итак, ваш запрос равенна это:

SELECT *
FROM TBL_A
WHERE COLUMN_A BETWEEN "1st Day of Current Month"
                   AND "Last Day of Current Month"

Я не могу оставить это невысказанным, мне не нравится, как работает ваш текущий запрос, потому что "Last Day of Current Month" равно НЕ фактическому концу месяца, который24 часа после 2018-09-30 00:00:00+00000

Существует гораздо лучший способ точно определить требуемый диапазон дат (на мой взгляд):

select
  DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)   [Current Month Starts At]
, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())+1, 0) [Current Month Finishes At]

= 2018-09-01 00:00:00+00000 2018-10-01 00:00:00+00000 

, и я быпереписать ваш запрос следующим образом:

SELECT *
FROM TBL_A
WHERE COLUMN_A >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)   -- "Current Month Starts At"
  AND COLUMN_A  < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())+1, 0) -- "Current Month Finishes At"

При таком подходе все данные за текущий месяц будут выбраны независимо от точности времени в COLUMN_A (т. е. типы данных: date, smalldatetime, datetime или datetime2)

Большинство запросов, перечисленных выше, можно выполнить здесь: http://rextester.com/CTQ4148

0 голосов
/ 21 сентября 2018

Создание измерения даты может действительно упростить подобные вещи;особенно если вы хотите добавить столбцы для финансового месяца или чего-то еще.Извлечение меток даты или значений из таблицы, присвоение их переменным и использование их в вашем запросе.Проще и чище.Меньше места для ошибок.Уверен, что этот запрос надежный, но вам следует проверить несколько записей, если вы решите его использовать.

Вот таблица:

CREATE TABLE dbo.Dates (
    DateId DATE NOT NULL CONSTRAINT PK_Dates PRIMARY KEY,
    StartDatetime DATETIME2(7) NOT NULL,
    EndDatetime DATETIME2(7) NOT NULL,
    DateFullName NVARCHAR(30) NOT NULL,
    DayOfWeekNumber TINYINT NOT NULL,
    DayOfWeekdayNumber TINYINT NOT NULL,
    DayCode INT NOT NULL,
    DayOFWeekNameShort NVARCHAR(4) NOT NULL,
    DayOFWeekNameLong NVARCHAR(9) NOT NULL,
    DayOfMonthNumber TINYINT NOT NULL,
    DayOfQuarterNumber TINYINT NOT NULL,
    DayOfYearNumber SMALLINT NOT NULL,
    WeekOfMonthNumber TINYINT NOT NULL,
    WeekOfQuarterNumber TINYINT NOT NULL,
    WeekOfYearNumber TINYINT NOT NULL,
    WeekStart DATE NOT NULL,
    WeekEnd DATE NOT NULL,
    WeekStartDatetime DATETIME2(7) NOT NULL,
    WeekEndDatetime DATETIME2(7) NOT NULL,
    WeekPercentComplete FLOAT NOT NULL,
    WeekPercentRemaining FLOAT NOT NULL,
    MonthNumber TINYINT NOT NULL,
    MonthCode INT NOT NULL,
    MonthNameLong NVARCHAR(9) NOT NULL,
    MonthNameShort NVARCHAR(9) NOT NULL,
    MonthYearNameLong NVARCHAR(15) NOT NULL,
    MonthYearNameShort NVARCHAR(15) NOT NULL,
    MonthStart DATE NOT NULL,
    MonthEnd DATE NOT NULL,
    MonthStartDatetime DATETIME2(7) NOT NULL,
    MonthEndDatetime DATETIME2(7) NOT NULL,
    MonthPercentComplete FLOAT NOT NULL,
    MonthPercentRemaining FLOAT NOT NULL,
    QuarterNumber TINYINT NOT NULL,
    QuarterStart DATE NOT NULL,
    QuarterEnd DATE NOT NULL,
    QuarterStartDatetime DATETIME2(7) NOT NULL,
    QuarterEndDatetime DATETIME2(7) NOT NULL,
    QuarterShort NVARCHAR(2) NOT NULL,
    QuarterLong NVARCHAR(9) NOT NULL,
    QuarterPercentComplete FLOAT NOT NULL,
    QuarterPercentRemaining FLOAT NOT NULL,
    YearNumber SMALLINT NOT NULL,
    YearStart DATE NOT NULL,
    YearEnd DATE NOT NULL,
    YearStartDatetime DATETIME2(7) NOT NULL,
    YearEndDatetime DATETIME2(7) NOT NULL,
    YearPercentComplete FLOAT NOT NULL,
    YearPercentRemaining FLOAT NOT NULL,
    WeekOfMonthOccurance TINYINT NOT NULL,
    WeekOfQuarterOccurance TINYINT NOT NULL,
    WeekOfYearOccurance TINYINT NOT NULL,
    IsWeekday TINYINT NOT NULL,
    IsWeekend TINYINT NOT NULL,
    IsHoliday TINYINT NOT NULL,
    HolidayName NVARCHAR(50) NULL,
    ModifiedDateTime DATETIME2(7) CONSTRAINT DF_Dates_ModifiedDateTime DEFAULT(SYSUTCDATETIME()) NOT NULL,
    [Version] ROWVERSION NOT NULL
    )
GO

CREATE UNIQUE NONCLUSTERED INDEX IX_Dates_StartDatetime_EndDatetime ON dbo.Dates (
    StartDatetime ASC,
    EndDatetime ASC
    )
GO

CREATE NONCLUSTERED INDEX IX_Dates_WeekStartDatetime_WeekEndDatetime ON dbo.Dates (
    WeekStartDatetime ASC,
    WeekEndDatetime ASC
    )
GO

CREATE NONCLUSTERED INDEX IX_Dates_MonthStartDatetime_MonthEndDatetime ON dbo.Dates (
    MonthStartDatetime ASC,
    MonthEndDatetime ASC
    )
GO

CREATE NONCLUSTERED INDEX IX_Dates_QuarterStartDatetime_QuarterEndDatetime ON dbo.Dates (
    QuarterStartDatetime ASC,
    QuarterEndDatetime ASC
    )
GO

CREATE NONCLUSTERED INDEX IX_Dates_YearStartDatetime_YearEndDatetime ON dbo.Dates (
    YearStartDatetime ASC,
    YearEndDatetime ASC
    )
GO

Вот начальный сценарий:

SET DATEFIRST 7;

DECLARE @FDate DATE,
    @TDate DATE,
    @Now DATETIME2(7) = SYSUTCDATETIME();

/******************************************************************************
DATE RANGE TO BUILD TABLE DATA
*******************************************************************************/

SET @FDate = '1900-01-01';
SET @TDate = '2099-12-31';

/******************************************************************************
DECLARE TABLE VARIABLES FOR WEEK / MONTH / QUARTER DATA POINTS
*******************************************************************************/

DECLARE @OccuranceMonth TABLE (
    FDate INT NOT NULL,
    TDate INT NOT NULL,
    Occurance INT NOT NULL,
    UNIQUE CLUSTERED (FDate,TDate)
);

INSERT INTO @OccuranceMonth
VALUES
(1,7,1),
(8,14,2),
(15,21,3),
(22,28,4),
(29,31,5);

DECLARE @OccuranceQuarter TABLE (
    FDate INT NOT NULL,
    TDate INT NOT NULL,
    Occurance INT NOT NULL,
    UNIQUE CLUSTERED (FDate,TDate)
);

INSERT INTO @OccuranceQuarter
VALUES
(1,7,1),
(8,14,2),
(15,21,3),
(22,28,4),
(29,35,5),
(36,42,6),
(43,49,7),
(50,56,8),
(57,63,9),
(64,70,10),
(71,77,11),
(78,84,12),
(85,91,13),
(92,98,14);

DECLARE @OccuranceYear TABLE (
    FDate INT NOT NULL,
    TDate INT NOT NULL,
    Occurance INT NOT NULL,
    UNIQUE CLUSTERED (FDate,TDate)
);

INSERT INTO @OccuranceYear
VALUES
(1,7,1),
(8,14,2),
(15,21,3),
(22,28,4),
(29,35,5),
(36,42,6),
(43,49,7),
(50,56,8),
(57,63,9),
(64,70,10),
(71,77,11),
(78,84,12),
(85,91,13),
(92,98,14),
(99,105,15),
(106,112,16),
(113,119,17),
(120,126,18),
(127,133,19),
(134,140,20),
(141,147,21),
(148,154,22),
(155,161,23),
(162,168,24),
(169,175,25),
(176,182,26),
(183,189,27),
(190,196,28),
(197,203,29),
(204,210,30),
(211,217,31),
(218,224,32),
(225,231,33),
(232,238,34),
(239,245,35),
(246,252,36),
(253,259,37),
(260,266,38),
(267,273,39),
(274,280,40),
(281,287,41),
(288,294,42),
(295,301,43),
(302,308,44),
(309,315,45),
(316,322,46),
(323,329,47),
(330,336,48),
(337,343,49),
(344,350,50),
(351,357,51),
(358,364,52),
(365,371,53);

/******************************************************************************
CLEAR TABLE - YOU COULD CHANGE THE WHOLE THING INTO A MERGE
*******************************************************************************/

TRUNCATE TABLE dbo.Dates;

/******************************************************************************
USE RECURSION INSTEAD OF LOOP FOR DATE RANGE BASE
*******************************************************************************/

WITH DATES AS (
    SELECT
        @FDate AS DateId
    UNION ALL
    SELECT
        DATEADD(DD,1,DateId) AS DateId
    FROM DATES
    WHERE DATEADD(DD,1,DateId) <= @TDate
)

/******************************************************************************
INSERT FINAL RESULTS
*******************************************************************************/

INSERT INTO dbo.Dates (
    DateId,
    StartDatetime,
    EndDatetime,
    DateFullName,
    DayOfWeekNumber,
    DayOfWeekdayNumber,
    DayCode,
    DayOFWeekNameShort,
    DayOFWeekNameLong,
    DayOfMonthNumber,
    DayOfQuarterNumber,
    DayOfYearNumber,
    WeekOfMonthNumber,
    WeekOfQuarterNumber,
    WeekOfYearNumber,
    WeekStart,
    WeekEnd,
    WeekStartDatetime,
    WeekEndDatetime,
    WeekPercentComplete,
    WeekPercentRemaining,
    MonthNumber,
    MonthCode,
    MonthNameLong,
    MonthNameShort,
    MonthYearNameLong,
    MonthYearNameShort,
    MonthStart,
    MonthEnd,
    MonthStartDatetime,
    MonthEndDatetime,
    MonthPercentComplete,
    MonthPercentRemaining,
    QuarterNumber,
    QuarterStart,
    QuarterEnd,
    QuarterStartDatetime,
    QuarterEndDatetime,
    QuarterShort,
    QuarterLong,
    QuarterPercentComplete,
    QuarterPercentRemaining,
    YearNumber,
    YearStart,
    YearEnd,
    YearStartDatetime,
    YearEndDatetime,
    YearPercentComplete,
    YearPercentRemaining,
    WeekOfMonthOccurance,
    WeekOfQuarterOccurance,
    WeekOfYearOccurance,
    IsWeekday,
    IsWeekend,
    IsHoliday,
    HolidayName
    )
SELECT
    dte.DateId,
    CAST(dte.DateId AS DATETIME2(7)) AS StartDatetime,
    CAST(CAST(dte.DateId AS NVARCHAR(10)) + ' 23:59:59.9999999' AS DATETIME2(7)) AS EndDatetime,
    DATENAME(MONTH,dte.DateId) + ' ' + CAST(DAY(dte.DateId) AS NVARCHAR(2)) + ', ' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DateFullName,
    DATEPART(DW,dte.DateId) AS DayOfWeekNumber,
    REPLACE(DATEPART(DW,dte.DateId) - 1, 6, 0) AS DayOfWeekdayNumber,
    CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + 
        CASE WHEN LEN(MONTH(dte.DateId)) = 1 THEN '0' + CAST(MONTH(dte.DateId) AS NVARCHAR(2)) ELSE CAST(MONTH(dte.DateId) AS NVARCHAR(2)) END + 
        CASE WHEN LEN(DAY(dte.DateId)) = 1 THEN '0' + CAST(DAY(dte.DateId) AS NVARCHAR(2)) ELSE CAST(DAY(dte.DateId) AS NVARCHAR(2)) END AS INT) AS DayCode,
    CASE DATENAME(WEEKDAY,dte.DateId)
        WHEN 'Thursday' THEN 'Thur'
        ELSE LEFT(DATENAME(WEEKDAY,dte.DateId),3)
    END AS DayOFWeekNameShort,
    DATENAME(WEEKDAY,dte.DateId) AS DayOFWeekNameLong,
    DAY(dte.DateId) AS DayOfMonthNumber,
    DATEDIFF(d,DATEADD(qq,DATEDIFF(qq,0,dte.DateId),0),dte.DateId) + 1 AS DayOfQuarterNumber,
    DATEPART(dy,dte.DateId) AS DayOfYearNumber,
    DATEPART(WEEK,dte.DateId) - DATEPART(WEEK,DATEADD(MM,DATEDIFF(MM,0,dte.DateId),0)) + 1 AS WeekOfMonthNumber,
    DATEDIFF(WEEK,DATEADD(QUARTER,DATEDIFF(QUARTER,0,dte.DateId),0),dte.DateId) + 1 AS WeekOfQuarterNumber,
    DATEPART(WEEK,dte.DateId) AS WeekOfYearNumber,
    DATEADD(DD,-DATEPART(DW,dte.DateId) + 1,dte.DateId) AS WeekStart,
    DATEADD(DD,-DATEPART(DW,dte.DateId) + 7,dte.DateId) AS WeekEnd,
    CAST(DATEADD(DD,-DATEPART(DW,dte.DateId) + 1,dte.DateId) AS DATETIME) AS WeekStartDatetime,
    CAST(CAST(DATEADD(DD,-DATEPART(DW,dte.DateId) + 7,dte.DateId) AS NVARCHAR(10)) + ' 23:59:59.9999999' AS DATETIME2(7)) AS WeekEndDatetime,
    CAST(DATEPART(DW,dte.DateId) AS FLOAT) / 7 AS WeekPercentComplete,
    1 - CAST(DATEPART(DW,dte.DateId) AS FLOAT) / 7 AS WeekPercentRemaining,
    MONTH(dte.DateId) AS MonthNumber,
    CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + CASE WHEN LEN(MONTH(dte.DateId)) = 1 THEN '0' + CAST(MONTH(dte.DateId) AS NVARCHAR(2)) ELSE CAST(MONTH(dte.DateId) AS NVARCHAR(2)) END AS INT) AS MonthCode,
    DATENAME(MONTH,dte.DateId) AS MonthNameLong,
    CASE 
        WHEN LEN(DATENAME(MONTH,dte.DateId)) = 4 THEN DATENAME(MONTH,dte.DateId)
        WHEN DATENAME(MONTH,dte.DateId) = 'September' THEN 'Sept'
        ELSE LEFT(DATENAME(MONTH,dte.DateId),3)
    END AS MonthNameShort,
    DATENAME(MONTH,dte.DateId) + ' ' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS MonthYearNameLong,
    CASE 
        WHEN LEN(DATENAME(MONTH,dte.DateId)) = 4 THEN DATENAME(MONTH,dte.DateId)
        WHEN DATENAME(MONTH,dte.DateId) = 'September' THEN 'Sept'
        ELSE LEFT(DATENAME(MONTH,dte.DateId),3)
    END + ' ' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS MonthYearNameShort,
    CAST(CAST(MONTH(dte.DateId) AS NVARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DATE) AS MonthStart,
    DATEADD(DD,-1,DATEADD(MONTH,1,CAST(CAST(MONTH(dte.DateId) AS NVARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DATE))) AS MonthEnd,
    CAST(CAST(CAST(MONTH(dte.DateId) AS NVARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DATE) AS DATETIME) AS MonthStartDatetime,
    CAST(CAST(DATEADD(DD,-1,DATEADD(MONTH,1,CAST(CAST(MONTH(dte.DateId) AS VARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS VARCHAR(4)) AS DATE))) AS NVARCHAR(10)) + ' 23:59:59.9999999' AS DATETIME2(7)) AS MonthEndDatetime,
    CAST(DAY(dte.DateId) AS FLOAT) / CAST(DAY(DATEADD(DD,-1,DATEADD(MONTH,1,CAST(CAST(MONTH(dte.DateId) AS NVARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DATE)))) AS FLOAT) AS MonthPercentComplete,
    1 - (CAST(DAY(dte.DateId) AS FLOAT) / CAST(DAY(DATEADD(DD,-1,DATEADD(MONTH,1,CAST(CAST(MONTH(dte.DateId) AS NVARCHAR(2)) + '-01-' + CAST(YEAR(dte.DateId) AS NVARCHAR(4)) AS DATE)))) AS FLOAT)) AS MonthPercentRemaining,
    DATENAME(QQ,dte.DateId) AS QuarterNumber,
    CAST(DATEADD(q,DATEDIFF(q,0,dte.DateId),0) AS DATE) AS QuarterStart,
    CAST(DATEADD(d,-1,DATEADD(q,DATEDIFF(q,0,dte.DateId)+1,0)) AS DATE) AS QuarterEnd,
    CAST(CAST(DATEADD(q,DATEDIFF(q,0,dte.DateId),0) AS DATE) AS DATETIME) AS QuarterStartDatetime,
    CAST(CAST(CAST(DATEADD(d,-1,DATEADD(q,DATEDIFF(q,0,dte.DateId)+1,0)) AS DATE) AS NVARCHAR(10)) + ' 23:59:59.9999999' AS DATETIME2(7)) AS QuarterEndDatetime,
    'Q' + DATENAME(QQ,dte.DateId) AS QuarterShort,
    'Quarter ' + DATENAME(QQ,dte.DateId) AS QuarterLong,
    CAST(DATEDIFF(d,DATEADD(qq,DATEDIFF(qq,0,dte.DateId),0),dte.DateId) + 1 AS FLOAT) / CAST(DATEDIFF(DD,CAST(DATEADD(q,DATEDIFF(q,0,dte.DateId),0) AS DATE),CAST(DATEADD(d,-1,DATEADD(q,DATEDIFF(q,0,dte.DateId)+1,0)) AS DATE)) + 1 AS FLOAT) AS QuarterPercentComplete,
    1 - (CAST(DATEDIFF(d,DATEADD(qq,DATEDIFF(qq,0,dte.DateId),0),dte.DateId) + 1 AS FLOAT) / CAST(DATEDIFF(DD,CAST(DATEADD(q,DATEDIFF(q,0,dte.DateId),0) AS DATE),CAST(DATEADD(d,-1,DATEADD(q,DATEDIFF(q,0,dte.DateId)+1,0)) AS DATE)) + 1 AS FLOAT)) AS QuarterPercentRemaining,
    YEAR(dte.DateId) AS YearNumber,
    CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-01-01' AS DATE) AS YearStart,
    CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-12-31' AS DATE) AS YearEnd,
    CAST(CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-01-01' AS DATE) AS DATETIME) AS YearStartDatetime,
    CAST(CAST(CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-12-31' AS DATE) AS NVARCHAR(10)) + ' 23:59:59.9999999' AS DATETIME2(7)) AS YearEndDatetime,
    CAST(DATEPART(dy,dte.DateId) AS FLOAT) / CAST(DATEDIFF(DD,CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-01-01' AS DATE),CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-12-31' AS DATE)) + 1 AS FLOAT) AS YearPercentComplete,
    1 - (CAST(DATEPART(dy,dte.DateId) AS FLOAT) / CAST(DATEDIFF(DD,CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-01-01' AS DATE),CAST(CAST(YEAR(dte.DateId) AS NVARCHAR(4)) + '-12-31' AS DATE)) + 1 AS FLOAT)) AS YearPercentRemaining,
    a.Occurance AS WeekOfMonthOccurance,
    b.Occurance AS WeekOfQuarterOccurance,
    c.Occurance AS WeekOfYearOccurance,
    CASE
        WHEN DATEPART(DW,dte.DateId) BETWEEN 2 AND 6 THEN 1
        ELSE 0
    END AS IsWeekday,
    CASE
        WHEN DATEPART(DW,dte.DateId) IN (1,7) THEN 1
        ELSE 0
    END AS IsWeekend,
    0 AS IsHoliday,
    NULL AS HolidayName
FROM DATES AS dte
LEFT JOIN @OccuranceMonth AS a
    ON 1 = 1
    AND DAY(dte.DateId) BETWEEN a.FDate AND a.TDate
LEFT JOIN @OccuranceQuarter AS b
    ON 1 = 1
    AND DATEDIFF(d,DATEADD(qq,DATEDIFF(qq,0,dte.DateId),0),dte.DateId) + 1 BETWEEN b.FDate AND b.TDate
LEFT JOIN @OccuranceYear AS c
    ON 1 = 1
    AND DATEPART(dy,dte.DateId) BETWEEN c.FDate AND c.TDate
OPTION (MAXRECURSION 0);

/******************************************************************************
HOLIDAY FLAGGING
*******************************************************************************/

-- New Year's Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'New Year''s Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 1
    AND DAY(dte.DateId) = 1
    AND dte.IsHoliday = 0;

-- President's Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'President''s Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 2
    AND dte.WeekOfMonthOccurance = 3
    AND dte.DayOfWeekNumber = 2
    AND dte.IsHoliday = 0;

-- Memorial Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Memorial Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 5
    AND DAY(dte.DateId) BETWEEN 25 AND 31
    AND dte.DayOfWeekNumber = 2
    AND dte.IsHoliday = 0;

-- Independence Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Independence Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 7
    AND DAY(dte.DateId) = 4
    AND dte.IsHoliday = 0;

-- Labor Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Labor Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 9
    AND dte.DayOfWeekNumber = 2
    AND dte.WeekOfMonthOccurance = 1
    AND dte.IsHoliday = 0;

--Veteran's Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Veteran''s Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 11
    AND DAY(dte.DateId) = 11
    AND dte.IsHoliday = 0;

-- Thanksgiving Day

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Thanksgiving Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 11
    AND dte.WeekOfMonthOccurance = 4
    AND dte.DayOfWeekNumber = 5
    AND dte.IsHoliday = 0;

-- Black Friday

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Black Friday',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 11
    AND dte.WeekOfMonthOccurance = 4
    AND dte.DayOfWeekNumber = 6
    AND dte.IsHoliday = 0;

-- Christmas Day'

UPDATE dte
SET dte.IsHoliday = 1,
    dte.HolidayName = 'Christmas Day',
    dte.ModifiedDateTime = @Now
FROM dbo.Dates AS dte
WHERE MONTH(dte.DateId) = 12
    AND DAY(dte.DateId) = 25
    AND dte.IsHoliday = 0;

Вот несколько примеров сценариев (есть также столбцы с начальной и конечной датой для каждого дня / недели / месяца / года):

DECLARE @BaseDate DATE,
    @FromDate DATE,
    @ToDate DATE;

SET @BaseDate = SYSUTCDATETIME();

/******************************************************************************
THIS IS WHERE YOU WOULD FETCH A SPECIFIC DATE TO GET ALL KINDS OF INFO ON IT.
A DATE DIMENSION IS ESPECIALLY USEFUL WHEN CREATING REPORTS.
*******************************************************************************/

SELECT
    @FromDate = dte.MonthStart,
    @ToDate = dte.MonthEnd
FROM dbo.Dates AS dte
WHERE dte.DateId = @BaseDate;

SELECT *
FROM TBL_A
WHERE COLUMN_A BETWEEN @FromDate AND @ToDate;
...