代码之家  ›  专栏  ›  技术社区  ›  Mark Brady

在SQL SERVER 2008中,使用日期的间隔是否实际起作用

  •  4
  • Mark Brady  · 技术社区  · 15 年前

    根据 cdonner ,在他的回答中 here 在他的 blog .

    他声称,两个日期之间产生的结果不一致

    从他的博客:

    select
        case when '9/1/08' between '9/1/08' and '9/15/08'
            then 'in' else 'out' end as s1,
        case when '9/1/08' between '8/28/08' and '9/1/08'
            then 'in' else 'out' end as s2
    
    s1   s2
    ---- ----
    in   in
    
    (1 row(s) affected)
    select
        case when '1/1/08' between '1/1/08' and '2/1/08'
            then 'in' else 'out' end as s1,
        case when '1/1/08' between '12/31/07' and '1/1/08'
            then 'in' else 'out' end as s2
    
    s1   s2
    ---- ----
    in   out
    
    (1 row(s) affected
    

    请注意,第二个查询中的S2答案显示“Out”,而日期显然应该是in。

    根据 cdonner

    SQL中日期时间类型的最低有效位为3毫秒

    请原谅我的SQLServer问题。我主要讲甲骨文,所以这可能很难看。但是,当我接受他的查询(证明存在问题)并用datetime变量替换他的字符串时,我得到了正确的输出。

    DECLARE @Jan108 datetime
    DECLARE @Feb108 datetime
    DECLARE @Dec3107 datetime
    
    SET @Jan108 = '1/1/08'
    SET @Feb108 = '2/1/08'
    SET @Dec3107 = '12/31/07'
    
    select
        case when @Jan108 between @Jan108 and @Feb108
            then 'in' else 'out' end as s1,
        case when @Jan108 between @Dec3107 and @Jan108
            then 'in' else 'out' end as s2
    

    注意: 这并不是试图解决一场争论或发动一场激烈的战争。我真正想了解的是,SQL Server BETWEEN的功能是否不如Oracle BETWEEN。我们在甲骨文中没有这样的问题。

    8 回复  |  直到 7 年前
        1
  •  6
  •   Quassnoi    15 年前

    在Oracle中:

    select
        case when '1/1/08' between '1/1/08' and '2/1/08'
            then 'in' else 'out' end as s1,
        case when '1/1/08' between '12/31/07' and '1/1/08'
            then 'in' else 'out' end as s2
    FROM dual
    
    in out
    

    这里比较的是字符串,而不是日期。

    什么都没有 BETWEEN 12/31/07 and 1/1/08 2 追求 / ASCII

        2
  •  4
  •   GregD    15 年前

    我必须用这样的东西:

    Declare @BeginDate SmallDateTime
    Declare @EndDate SmallDateTime
    Set @BeginDate = '2007-08-01'
    Set @EndDate = '2007-08-31'
    
    Select *
    From dbo.table1 a
    Where a.session_date Between @BeginDate + ' 00:00:00' And @EndDate + ' 23:59:59'
    Order By a.session_date asc
    

    在datetime的

        3
  •  2
  •   Jim H.    15 年前

    您在问题中给出的示例存在舍入问题,类似于浮点值1.0如何存储为0.99999。。。

    要准确地比较日期,您需要将值强制转换为datetime类型,然后进行比较。

    SELECT
    CASE 
        WHEN cast('1/1/08' as datetime) 
            BETWEEN cast('1/1/08' as datetime) AND cast('2/1/08' as datetime) 
        THEN 'in' ELSE 'out' 
    END AS s1,
    CASE 
        WHEN cast('1/1/08' as datetime) 
            BETWEEN cast('12/31/07' as datetime) AND cast('1/1/08' as datetime) 
        THEN 'in' ELSE 'out' 
    END AS s2
    

        4
  •  1
  •   Joel Coehoorn    15 年前

    你是对的,他的代码由于字符串比较而有缺陷。

    SELECT * FROM [MyTable] WHERE MyDateColumn BETWEEN @StartDate AND @EndDate
    

    SELECT * FROM [MyTable] WHERE MyDateColumn >= @StartDate AND MyDateColumn < @EndDate
    

        5
  •  0
  •   DJ.    15 年前

    因为他完全错了-这是比较字符串

    如果将它们强制转换为日期时间或用日期变量替换它们,则会起作用:

    select
        case when CAST('JAN 01 2008' as smalldatetime)
            between CAST('JAN 01 2008' as smalldatetime)
            and CAST('FEB 01 2008' as smalldatetime)
            then 'in' else 'out' end as s1,
        case when CAST('JAN 01 2008' as smalldatetime)
            between CAST('DEC 31 2007' as smalldatetime)
            and CAST('JAN 01 2008' as smalldatetime)
            then 'in' else 'out' end as s2
    
        6
  •  0
  •   cdonner    15 年前

    博客上的代码是胡说八道,我应该感谢马克向我指出这一点。 这个问题是存在的。它与BETWEEN无关,但与舍入有关(在某些情况下,舍入可能导致BETWEEN失败)。虽然SQL Server会舍入,.Net不会,但我在很短的时间内遇到了多个插入的问题,我假设我有不同的日期时间值,但由于舍入,它们在数据库中变得相同。 这篇文章很久以前就被更正了,代码示例仍然可以在SQLServer2008上使用。

    select convert(varchar(32), convert(datetime,
                                '9/1/08 00:00:00.005'), 121);
    
        7
  •  0
  •   druid    13 年前

    只是永远不要将BETWEEN与datetime值一起使用。在MySQL中我可以做到

    created >= CURDATE() - INTERVAL 1 DAY AND created < CURDATE()
    

    限定于昨天(全部)。

        8
  •  0
  •   Dan Alvear    11 年前

    非常有用的讨论!

    在'2013-01-01'和'2013-01-31'之间转换(varchar(8),[PostDate],112)为日期)

    “Cast”(“是必需的(相信我,我有足够的证据来证明它”),但不必声明变量,等等。