在“toDate”中选择NULL为日期范围

时间:2014-01-29 13:44:00

标签: mysql sql tsql

我有下表:

PriceId PriceType  FromDate   ToDate         Price  ElementId
1           F      2014-01-01  NULL          0.00900      1
3           F      2014-01-01  2014-02-01    0.31470      4
4           F      2014-01-01  NULL        432.00000      3
6           F      2014-02-01  NULL          0.30950      4
7           F      2014-02-01  NULL          0.28990      2

输入为ElementID = 4,fromDate和toDate

我想要一个元素的所有价格,其中from和todate在输入期间之间。 toDate是,但不包括。

因此,2014-01-28至2014-03-01应该返回记录3& 6 2014-01-28至2014-02-01应该只返回记录3。 2014-02-07至2014-03-01应该返回记录6.

任何人都可以帮我完成WHERE子句:

 WHERE ElementId = 4 AND...

... TIA

- 达格桑德。

3 个答案:

答案 0 :(得分:1)

目前还不完全清楚NULL ToDate的意义是什么。我认为这意味着“正在进行”,或者基本上是NOW()

在这种情况下,你需要

  WHERE whatever
    AND FromDate >= ?starting
    AND IFNULL(ToDate, NOW()) < ?ending

只要您的FromDate值始终位于ToDate值之前且?starting参数位于?ending之前,此功能就会正常运行。

此设计可能存在严重的效率问题。使用索引来搜索空值很难。

答案 1 :(得分:0)

fromDate <= :yourMaxDateParameterHere and ( ToDate >= :yourMinDateParameterHere or ToDate is null )

答案 2 :(得分:0)

明天睡个不醒; '2014-01-28'作为@FromDate(第一个参数)介于记录3的FromDate(大于'2014-01-01')和6(小于'2014-02-01')之间。

您可能想要考虑以下四个条件:

  • 您的FromDate(列值)需要小于ToDate(列值)。 - 检查
  • 您的@FromDate(变量/输入)需要小于@ToDate(变量/输入)。 - 检查
  • 您的FromDate需要[ between ) @FromDate@ToDate。 - 待办事项
  • 您的ToDate需要[ between ) @FromDate@ToDateNULL。 - 待办事项

SQL Fiddle是您问题的一个示例。在这种情况下,我选择使用OR来保留查询sargable - 尾随解释显示我添加的索引的键长度以不同的方式编写查询 - 只有前者使用整件事。

实际上,查询如下:

SELECT  PriceID, PriceType, FromDate, 
        ToDate, Price, ElementID
FROM    Price
WHERE   ElementID = @ElementID

    -- AND FromDate < ToDate -- First condition, bad record

    -- AND @FromDate < @ToDate -- Second condition, bad input

    AND FromDate >= @FromDate -- third condition, between "[" ( inclusive )
    AND FromDate < @ToDate    -- and between ")" ( exclusive )

    AND (   ToDate IS NULL
        OR  ToDate >= @FromDate ) -- forth condition, between "["
    AND (   ToDate IS NULL
        OR  ToDate < @ToDate );   -- and between ")".