/ / SQL Server: Zwraca wszystkie wiersze tabeli, której pole daty spełnia określone warunki daty - sql-server, sql-server-2008, datetime, sql-server-2008-r2, getdate

SQL Server: Zwraca wszystkie wiersze tabeli, które pole daty spełnia pewne warunki daty - sql-server, sql-server-2008, datetime, sql-server-2008-r2, getdate

Mam tabelę z dużą liczbą pracowników, powiedzmy tabelę „Pracownicy”. Ta tabela ma między innymi kolumnę daty. Powiedzmy, że ta kolumna nazywa się „InjuryDate”.

Chciałbym wybrać wszystkich pracowników, którzy spełniają poniższe warunki:

  1. Data InjuryDate przypada w bieżącym miesiącu, na przykład jeśli bieżącym miesiącem jest lipiec, chcę, aby wszyscy pracownicy: InjuryDate> = 01/07/2017 i InjuryDate <= 31/07/2017.
  2. Data urazu przypada między 20 dniem ostatniego miesiącai pierwszego dnia bieżącego miesiąca. Na przykład, jeśli bieżącym miesiącem jest lipiec, chcę, aby wszyscy pracownicy: InjuryDate> = 20/06/2017 i InjuryDate <01/07/2017.

Więc wzięto pod uwagę to, co zostało powiedziane tutaj (Biorąc pod uwagę, że SQL Server może w razie potrzeby użyć indeksu w kolumnie), zrobiłem poniższe zapytanie:

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)
)

Czy to prawda, czy jest jakiś lepszy sposób?

Używam programu SQL Server 2008.

Odpowiedzi:

2 dla odpowiedzi № 1

Spróbuj tego:

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;

Wydajność:

Id          InjuryDate
----------- ----------
2           2017-06-20
3           2017-07-19
4           2017-07-31

1 dla odpowiedzi nr 2

Zasadniczo potrzebujesz wszystkich rekordów z ostatniego 20 miesiąca do ostatniego dnia bieżącego miesiąca. Potrzebujesz LUB tutaj.

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

0 dla odpowiedzi № 3

. Usuń moją odpowiedź, ponieważ ktoś uważa, że ​​to kradzież