SQL Server: вернуть все строки таблицы, поле даты которых удовлетворяет некоторым условиям даты

У меня есть таблица с большим количеством сотрудников, скажем, таблица «Сотрудники». В этой таблице есть столбец даты среди других. Допустим, этот столбец называется «Дата травмы».

Я хотел бы выбрать всех сотрудников, которые удовлетворяют следующим условиям:

  1. InjuryDate находится в текущем месяце, например, если текущий месяц — июль, я хочу, чтобы все сотрудники: InjuryDate >= 07.01.2017 и InjuryDate ‹= 31.07.2017.
  2. InjuryDate находится между 20-м днем ​​прошлого месяца и первым днем ​​текущего месяца. Например, если текущий месяц — июль, мне нужны все сотрудники, которые: InjuryDate >= 20.06.2017 и InjuryDate ‹ 07.01.2017.

Итак, учтите, что сказано здесь (принимая во внимание, что SQL Server может использовать индекс для столбца, если это необходимо), я сделал следующий запрос:

DECLARE @today datetime = getdate()

DECLARE @Day int  = 20
DECLARE @Month int  = MONTH(dateadd(month, -1, @today))
DECLARE @Year int = YEAR(dateadd(month, -1, @today))
DECLARE @EarlyDate datetime = cast(cast(@Year*10000 + @Month*100 + @Day as varchar(255)) as date)

SELECT *
FROM   Employees
WHERE  (
         -- Condition 1
         InjuryDate >= cast(@today - day(@today) + 1 as date) 
            AND
         InjuryDate < dateadd(month, 1, cast(@today - day(@today) + 1 as date) )
       )
         OR
       (    
         -- Condition 2
         InjuryDate >= @EarlyDate
            AND 
         InjuryDate < cast(@today - day(@today) + 1 as date) 
       )

Это правильно, или есть другой лучший способ сделать это?

Я использую SQL Server 2008.


person Rodri    schedule 28.07.2017    source источник


Ответы (3)


Попробуй это:

DECLARE @today date = getdate();

DECLARE @todayDay int  = datepart(day, @today);
DECLARE @earlyDate date = dateadd(day, 19, DATEADD(month, DATEDIFF(month, 0, @today) - 1, 0));
DECLARE @nextMonthFirstDayDate date = DATEADD(month, DATEDIFF(month, 0, @today) + 1, 0);

SELECT *
FROM (
        VALUES  (1, '2017-06-19'),
                (2, '2017-06-20'),
                (3, '2017-07-19'),
                (4, '2017-07-31'),
                (5, '2017-08-01')
     ) AS Employees(Id,InjuryDate)
WHERE  InjuryDate >= @earlyDate AND InjuryDate < @nextMonthFirstDayDate;

Выход:

Id          InjuryDate
----------- ----------
2           2017-06-20
3           2017-07-19
4           2017-07-31
person Ruslan K.    schedule 28.07.2017
comment
Похоже, это не работает, когда @today 31.07.2017, а не 20-го числа. - person Rodri; 31.07.2017

В основном вам нужно получить все записи с 20-го числа последнего месяца до последнего дня текущего месяца. Вам нужно ИЛИ здесь.

DECLARE @end_range DATE= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)),
    @start_rage DATE= DATEADD(m, DATEDIFF(m, 0, DATEADD(m, DATEDIFF(m, 0, GETDATE()), -1)), 19)  

SELECT *
FROM   Employees
WHERE InjuryDate BETWEEN @start_range AND @end_rage
person Dmitrij Kultasev    schedule 28.07.2017
comment
почему вы используете секунды в @start_range? Это необходимо? или достаточно учесть только дату и отбросить время? Также в вашем ответе есть переключатель start_range и end_range, исправьте, пожалуйста. - person Rodri; 28.07.2017
comment
Также мое поле InjuryDate представляет собой только столбец даты, я имею в виду, что в нем нет времени, время установлено на 00:00:00.0. В той же таблице у меня есть еще один столбец «InjuryTime», который содержит только время (без даты). - person Rodri; 28.07.2017
comment
несмотря на то, что поле InjuryDate в моем столбце содержит только дату, я думаю, что ваше решение в порядке. Не могли бы вы подтвердить меня, пожалуйста? - person Rodri; 28.07.2017
comment
@Rodri, вы должны выбрать лучший ответ и принять его: stackoverflow.com/help/someone-answers - person Ruslan K.; 28.07.2017
comment
исправлены конечные и начальные диапазоны и использование DATE вместо DATETIME - person Dmitrij Kultasev; 28.07.2017

. Удалите мой ответ, так как кто-то считает, что это кража

person PRAVIN NALIYAPARA    schedule 31.07.2017
comment
@РусланК. Я удалил свой ответ, так как вы чувствуете, что это кража, это не кража, а только представление другими способами. - person PRAVIN NALIYAPARA; 03.08.2017