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:
- 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.
- 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 № 1Spró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ż