Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Работа с датой


Автор: Larrr 25.6.2007, 10:59
Такой вопрос - в базе есть таблица со стобцами "цена" и "дата", где дата - дата записи цены в таблицу. Как выселектить все цены, не старше 15 дней?

SELECT price FROM Ad WHERE DATEDIFF(day, Ad.insert_time, getdate()) < 15; 

не работает...

Автор: SergKO 25.6.2007, 13:30
Попробуйте так
Код

declare @t table (price money, insert_time datetime);

    insert into @t
        select 1, '20070101'
        union all
        select 2, '20070425'
        union all
        select 3, '20070525'
        union all
        select 4, '20070625'
        union all
        select 5, '20070615'
        union all
        select 6, '20070610'
        union all
        select 7, '20070611'
        union all
        select 8, '20070527'
        union all
        select 9, '20070529';

declare @d    datetime;

    select @d = dateadd(day, -15, getdate());

    select price 
    from @t
    where insert_time >= @d;


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

Автор: kobra 25.6.2007, 13:56
запрос верный. 
что не работает?

Автор: SergKO 25.6.2007, 14:37
Цитата(kobra @  25.6.2007,  13:56 Найти цитируемый пост)
запрос верный. 
что не работает? 


Вообще-то, да. Запрос-то верный (просто совсем нерациональный). А в самом деле, в чем проблема проявляется?

Автор: Kolia 17.7.2007, 16:33
Даты сравниваются достаточно часто. Поэтому я написал отдельную функцыю для сравнения дат uf_compare_dates(date1, date2, with_time)

date1 - datetime. Дата от
date2 - datetime. Дата до
with_time - bit. 1 или 0. 1 - сравнивать с учетом времени. 0 - сравнивать без учета времени.

Ведь если вчера внесли информацию в 15.00, а сегодня в 12.00 ты запустишь свой селект, то ничего не получишь, так как сутки еще не прошли.

Внутри функции даты конвертирую в числа. Если (with_time = 0) - в int, (with_time = 1) - в decimal.


Вобщем, вот моя реализация
Код

ALTER       FUNCTION tbl.uf_date2decimal(
    @date datetime
)
RETURNS decimal(24,8)
AS
BEGIN
    RETURN    convert(decimal(24,8), @date)
END


Код

ALTER   FUNCTION tbl.uf_date2int( @date datetime)
RETURNS bigint
AS
BEGIN
    RETURN (floor( tbl.uf_date2decimal(@date) ))
END



Код

ALTER        FUNCTION tbl.uf_compare_dates(
    @date1 datetime,
    @date2 datetime,
    @with_time bit

)
RETURNS integer
AS
BEGIN

    DECLARE @result integer

    IF (@with_time = 0)
    BEGIN
        IF (tbl.uf_date2int(@date1) < tbl.uf_date2int(@date2))
            SET @result = 1
        ELSE IF (tbl.uf_date2int(@date1) > tbl.uf_date2int(@date2))
            SET @result = -1
        ELSE --    dates are equal
            SET @result = 0
    END
    ELSE
    BEGIN
        IF (tbl.uf_date2decimal(@date1) < tbl.uf_date2decimal(@date2))
            SET @result = 1
        ELSE IF (tbl.uf_date2decimal(@date1) > tbl.uf_date2decimal(@date2))
            SET @result = -1
        ELSE --    dates are equal
            SET @result = 0
    END

    RETURN    @result
END



Если нужна дата без времени
Код

ALTER       FUNCTION tbl.uf_date_floor(
    @date datetime
)
RETURNS datetime
AS
BEGIN
    DECLARE @date_i bigint

    IF @date IS NULL
        RETURN @date
    
    SET @date_i = tbl.uf_date2int(@date)
    SET @date = tbl.uf_int2date(@date_i)

    RETURN    @date
END


Код

ALTER       FUNCTION tbl.uf_int2date(
    @date_i bigint
)
RETURNS datetime
AS
BEGIN
    RETURN    convert(datetime, @date_i)
END

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)