Преобразование INT в DATE, а затем использование GETDATE при преобразовании?

Я пытаюсь преобразовать результаты из столбца INT в DATE, чтобы функция GETDATE была совместима с этим столбцом. Дата в настоящее время в формате ггггммдд

Это то, что у меня есть до сих пор, основываясь на том, что я смог найти, но я уверен, что это совершенно неправильно.

...AND (dbo.V_HEAD.LF_DATE CONVERT(DATE,(CONVERT(INT, LF_DATE)) >= GETDATE-28)

AND (dbo.V_HEAD.LF_DATE CONVERT(DATE,(CONVERT(INT, LF_DATE)) <= GETDATE)...

Я хочу, чтобы результаты были квалифицированы LF_DATE и за последние 28 дней.

В остальном скрипт работает корректно. Где я ошибаюсь и как это исправить?


person KMoe    schedule 09.08.2016    source источник
comment
Ваш sql недействителен. Какой тип LF_DATE?   -  person Hamlet Hakobyan    schedule 10.08.2016
comment
вместо GETDATE вы можете попробовать использовать функцию DATEADD, чтобы получить диапазон дат.   -  person dub stylee    schedule 10.08.2016
comment
LF_DATE — ЦЕЛОЕ ЧИСЛО   -  person KMoe    schedule 10.08.2016
comment
Я не понимаю этот синтаксис: AND (dbo.V_HEAD.LF_DATE CONVERT(DATE,(CONVERT(INT, LF_DATE)) ›= GETDATE-28) .   -  person DVT    schedule 10.08.2016
comment
Извините, в заявлении есть несколько вариантов. Я только что вырезал часть сценария, с которой у меня возникли проблемы. Мне нужна хранимая процедура, которая будет возвращать результаты за последние 28 дней независимо от того, когда я ее запускаю. Вот почему я хотел использовать GETDATE   -  person KMoe    schedule 10.08.2016


Ответы (3)


Обновить
Следуя вашим комментариям, я создал некоторые образцы данных, чтобы проверить свой ответ:
Создайте и заполните образцы данных (Пожалуйста, сохраните этот шаг в ваших будущих вопросах)

DECLARE @T as TABLE
(
    Id int,
    ActualDate Date,
    LF_Date int
)

INSERT INTO @T (Id, ActualDate) VALUES
(10, DATEADD(DAY, -5, GETDATE())),
(9, DATEADD(DAY, -10, GETDATE())),
(8, DATEADD(DAY, -15, GETDATE())),
(7, DATEADD(DAY, -20, GETDATE())),
(6, DATEADD(DAY, -25, GETDATE())),
(5, DATEADD(DAY, -30, GETDATE())),
(4, DATEADD(DAY, -35, GETDATE())),
(3, DATEADD(DAY, -40, GETDATE())),
(2, DATEADD(DAY, -45, GETDATE())),
(1, DATEADD(DAY, -50, GETDATE()))

UPDATE @T 
SET LF_Date = YEAR(ActualDate) * 10000 + MONTH(ActualDate) * 100 + DAY(ActualDate)

Данные тестового образца:

SELECT *
FROM @T 

Полученные результаты:

Id          ActualDate  LF_Date
----------- ----------  -----------
10          2016-08-09  20160809
9           2016-08-04  20160804
8           2016-07-30  20160730
7           2016-07-25  20160725
6           2016-07-20  20160720
5           2016-07-15  20160715
4           2016-07-10  20160710
3           2016-07-05  20160705
2           2016-06-30  20160630
1           2016-06-25  20160625

Как вы можете видеть, столбец LF_Date в образце таблицы представляет собой столбец int, который сохраняет дату как yyyyMMdd, как и в вопросе.

Запрос:

DECLARE @DateAsInt int,
        @Date date = GETDATE();

SELECT @DateAsInt = YEAR(@Date) * 10000 + MONTH(@Date) * 100 + DAY(@Date);

SELECT *
FROM @T 
WHERE LF_DATE >= @DateAsInt - 28
AND LF_DATE <= @DateAsInt

Полученные результаты:

Id          ActualDate  LF_Date
----------- ----------  -----------
10          2016-08-09  20160809
9           2016-08-04  20160804

Вывод:

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

Первая версия
Предполагая, что версия вашего сервера Sql 2012 или более поздняя, ​​вы можете использовать некоторые математические вычисления и DATEFROMPARTS встроенная функция:

DECLARE @IntDate int = 20160322

SELECT  DATEFROMPARTS (
            (@IntDate - (@IntDate % 10000)) / 10000,
            (@IntDate % 1000) / 100,
            @IntDate % 100
        ) As [Date]

Полученные результаты:

Date
2016-03-22

Однако преобразование date в int будет проще и, вероятно, будет иметь лучшую производительность:

DECLARE @Date date = '2016-03-22'

SELECT  YEAR(@Date) * 10000 + 
        MONTH(@Date) * 100 + 
        DAY(@Date) As [Int]

Полученные результаты:

Int
20160322

Чтобы поставить это в контексте вашего вопроса, вычислите значение int текущей даты перед вашим запросом:

DECLARE @DateAsInt int,
        @Date date = GETDATE();
    
SELECT @DateAsInt = YEAR(@Date) * 10000 + MONTH(@Date) * 100 + DAY(@Date);

И затем в вашем предложении where вы просто пишете это:

...
AND LF_DATE >= @DateAsInt - 28
AND LF_DATE <= @DateAsInt
...

В любом случае вам будет лучше, если вы сможете изменить структуру таблицы и заменить этот столбец int столбцом даты. Прочтите плохие привычки Аарона Бертрана, чтобы kick : выбор неправильного типа данных.

person Zohar Peled    schedule 10.08.2016
comment
Спасибо, теперь это частично работает, проблема в том, что результаты не распространяются на предыдущий месяц, когда я использую @DateAsInt - 28 - person KMoe; 11.08.2016
comment
Спасибо, теперь это частично работает, проблема в том, что результаты не распространяются на предыдущий месяц. Я запустил @DateAsInt - 28 сегодня, он возвращает результаты только до начала месяца. То есть 01 августа 2016 г. - person KMoe; 11.08.2016

Возможно, это может помочь

Select DateAdd(DD,-28,cast(cast(20160809 as varchar(8)) as date))

Возврат 2016-07-12

Однако, поскольку ваши данные имеют тип int, я думаю, было бы более эффективно преобразовать желаемый диапазон дат в тип int, а не выполнять вычисления на уровне строк.

Declare @DateR1 int = Format(DateAdd(DD,-28,GetDate()),'yyyyMMdd')
Declare @DateR2 int = Format(GetDate(),'yyyyMMdd')

Select DateR1=@DateR1,DateR2=@DateR2

Возвращает

DateR1      DateR2
20160712    20160809
person John Cappelletti    schedule 09.08.2016

@ Зохар Пелед, кажется, я взломал его! Он вычитает 28 как целое число, а не дни. Проблема 20160809 - 28 = 20160781, что нехорошо

Желаемые результаты будут

SELECT * FROM @T WHERE LF_DATE >= @DateAsInt - 28 (DAYS) AND LF_DATE ‹= @DateAsInt

Идентификатор ActualDate LF_Date


10 2016-08-09 20160809 9 2016-08-04 20160804 8 2016-07-30 20160730 7 2016-07-25 20160725 6 2016-07-20 20160720 5 2016-07-15 20160715

Поскольку 20160809 - 28 DAYS будет включать даты с 20160712 года.

Чтобы обойти это, нужно было вычесть 97 вместо 28.

Это не очень чисто, должен быть лучший способ...

person KMoe    schedule 16.08.2016
comment
Да, есть лучший способ — не используйте неправильный тип данных. Храните даты в столбце даты. - person Zohar Peled; 21.08.2016
comment
Я унаследовал эту базу данных. Я не имел ничего общего со структурой - person KMoe; 26.08.2016