2015-02-13 4 views
3

Проблемы с пониманием того, как заставить предложение Where работать с этой структурой даты.SQL Date Logic

Вот основная логика. Я хочу данные только с предыдущего марта 1 и заканчивая датой дня.

Пример # 1: Так сегодня 13 февраля 2015 Это будет означать, мне нужно данные между (2014-03-01 и 2015-02-12)

Пример # 2: Say сегодня 20 марта 2015 Это Это означало бы, мне нужно данные между (2015-03-01 и 2015-03-19)

где логика может работать, но он не хотел бы преобразовать «3/1/'+ год. Но я не уверен, как еще это выразить. Первое предложение - это прекрасная секция Case, которая сломана.

Запрос

SELECT [Request Date], [myItem] 
    FROM myTable 
    WHERE [Request Date] < CONVERT(VARCHAR(10), GETDATE(), 102) 
     AND [Request Date] = CASE WHEN 
      CONVERT(VARCHAR(10), GETDATE(), 102) < 
      CONVERT(VARCHAR(12), '3/1/' + DATEPART (year , GETDATE()) , 114) 
     THEN [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART (year , GETDATE()-365) , 114) 
     ELSE [Request Date] > CONVERT(VARCHAR(12), '3/1/' + DATEPART (year , GETDATE() , 114) 
     END 

Я также попытался

AND [Request Date] = CASE WHEN 
      CONVERT(VARCHAR(10), GETDATE(), 102) < 
      '3/1/' + CONVERT(VARCHAR(12), DATEPART (YYYY , GETDATE())) 
     THEN [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART (YYYY , GETDATE()-364)) 
     ELSE [Request Date] > '3/1/' + CONVERT(VARCHAR(12), DATEPART (YYYY , GETDATE())) 
     END 
+0

Вы можете указать тип SQL, который вы используете? –

+0

выглядит как TSQL – dotjoe

+0

Извините, я должен был указать это. Это SQL 2008 – Flexpadawan

ответ

1

Пробуйте этот пункт where.

WHERE [Request Date] 
     BETWEEN Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE) 
        AND Getdate() - 1 

Здесь Cast(CONVERT(VARCHAR(4), Year(Getdate())-1)+ '-03-01' AS DATE) придет первый день месяца марша. С этим добавьте -1 год, чтобы получить отправную точку.

Getdate() - 1 будет определять конечную точку

+1

Этот код просто создает предыдущий год, основанный на начале этого месяца, и вообще не разбивается 1 марта. –

+0

@KevinCook - Обновлено –

+1

Этот код провалился в марте этого года. Он всегда тянет в предыдущем году не предыдущий марш 1-го. –

0

В Oracle, я бы вычислить нижнюю границу, как это:

add_months(trunc(add_months(sysdate, -2), 'YEAR'), 2) 

Другими словами - вычесть два месяца, круглые до начала года, затем добавьте два месяца.

Надеюсь, вы можете преобразовать это, чтобы использовать соответствующие функции TSQL.

1

Я бы предпочел создать переменные datetime для диапазона @from - @to, но если это для представления, я думаю, вы должны сделать это в предложении where.

SELECT [Request Date], [myItem] 
    FROM myTable 
    WHERE [Request Date] < cast(GETDATE() as date) 
     AND [Request Date] >= CASE WHEN 
      GETDATE() < CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4))) 
     THEN CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) - 1 as varchar(4))) 
     ELSE CONVERT(datetime, '3/1/' + cast(Year(GETDATE()) as varchar(4))) 
     END 
+1

Другое, тогда Type O varchar ... это сработало отлично. Спасибо dotjoe – Flexpadawan

+0

whoops :) thanks – dotjoe

1

Что-то вроде этого? Всегда с 1 марта, в прошлом году, если это сейчас 1 марта или ранее, и в противном случае в этом году.

SELECT [Request Date], [myItem] 
FROM myTable 
WHERE [Request Date] >= dateadd(month, 2, DATEADD(year, DATEDIFF(year, 0, dateadd(month, -2, dateadd(day, -1, getdate()))), 0)) 
and [Request Date] < DATEADD(day, DATEDIFF(day, 0, getdate()), 0) 

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

+0

Это отличная техника и будет работать в течение года. –

0

Позволяет работать с некоторыми тестовыми данными:

DECLARE @MyDate DATETIME = '3/13/2015' 

Going объявить некоторые переменные мы будем установить:

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 

В этом коде я проверяю, если мы до или после марша- , и если да, то мы будем использовать либо предыдущий год, либо в этом году для начальной точки (финансовый год?)

SELECT @StartDate = CASE WHEN DATEPART(MONTH, @MyDate) < 3 THEN 
    DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate) - 1, 0)) 
    ELSE 
    DATEADD(MONTH, 2, DATEADD(YEAR, DATEDIFF(YEAR, 0, @MyDate), 0)) 
    END, 
    @EndDate = DATEADD(DAY, DATEDIFF(DAY, 0, @MyDate), 0) 

Вот результат:
ВЫБРАТЬ @StartDate AS Start, @EndDate AS EndDate

Start     EndDate 
2015-03-01 00:00:00.000 2015-03-13 00:00:00.000 
0

Я бы сначала создать достаточно универсальный определяемую пользователем функцию, которая делает то, что мне нужно, таким образом:

create function dbo.start_of_fiscal_year 
(
    @today date , 
    @fiscal_year_start_month int 
) 
returns date 
as 
begin 
    set @today = case coalesce(@today,'') 
       when '' then current_timestamp 
       else   @today 
       end 
    declare @month_start    date = dateadd(day,1-datepart(day,@today),@today) 
    declare @fiscal_month_number  int = case sign(datepart(month,@month_start) - @fiscal_year_start_month) 
              when -1 then 13 
              else   1 
              end 
             + (datepart(month,@month_start) - @fiscal_year_start_month) 
    declare @fiscal_year_start  date = dateadd(month,[email protected]_month_number,@month_start) 

    return @fiscal_year_start 
end 
go 

После того, как вы есть, что вы можете сказать такие вещи, как

declare @today date = current_timetamp 
declare @fy_start date = start_of_fiscal_year(@today,3) 

select * 
from dbo.foo t 
where t.report_date >= @fy_start 
    and t.report_date < @today 

или даже

select fiscal_year = datepart(year,start_of_fiscal_year(t.report_date,3)) , count(*) 
from dbo.foo t 
group by datepart(year,start_of_fiscal_year(t.report_date,3)) 
0

Ваша нижняя граница должна быть такой. Вам просто нужно компенсировать год, когда месяц меньше 3 (март).

dateadd(
    yy, 
    year(current_timestamp) - 1900 + case when month(current_timestamp) < 3 then -1 else 0 end, 
    '19000301' 
) 

Нет причин вмешиваться в цепочку, и это очень упрощает логику. Я также предполагаю, что, когда текущая дата - 1 марта, вы хотите запросить весь прошлый год. Поэтому вам нужно немного настроить тест.

case when (month(dateadd(dd, -1, current_timestamp)) < 3 ... 

И просто для удовольствия:

dateadd(mm, (12-month(current_timestamp-1))/10*-12+2, cast(year(current_timestamp) as char(4)));