棘手的SQL我不能得到...日期和NULL

时间:2011-10-10 18:53:13

标签: sql sql-server-2005

想象一下有一些行项目的表

LineItemID   CountryID   Date
1             China      6/26/2011
2             China      6/27/2011
3             US         3/21/2011

我还有一张有一些费率的表:

CountryID  ExchangeRateDate   ExchangeRateDateTo   Rate
US           1/1/2011               NULL             1
China        6/1/2011               6/13/2011        6.06
China        6/13/2011              6/26/2011        6.13
China        6/26/2011              NULL             6.26

请注意,对于ExchangeRateDateTo,美国的费率不会改变为1的速率为NULL。我可以通过countryID加入表格没问题,我的问题是例如我如何才能加入国家ID,还可以使用FirstTable的日期与第二个表格ExchangeRateDate / To来获得正确的日期。

例如,我不能说

WHERE FirstTable.[Date] BETWEEN SecondTable.ExchangeRateDate AND SecondTable.ExchangeRateDateTo

因为例如中国的费率变为空(从2011年6月26日开始直到空) 所以基本上我正在寻找一种方法,以便使用6.26的比率得到中国的结果,因为日期是6 / 26-6 / 27。 6.13的汇率在6月26日结束,所以应该提高新汇率。

所以我的加入将是countryID加上使用日期范围来获取正确的费率,否则,如果我只加入countryid,你可以看到那会产生笛卡尔。

2 个答案:

答案 0 :(得分:3)

使用哨兵值

WHERE
    FirstTable.[Date] 
                 BETWEEN SecondTable.ExchangeRateDate
                 AND ISNULL(SecondTable.ExchangeRateDateTo, '99991231')

您也可以在JOIN中执行此操作

FROM
    FirstTable F
    JOIN
    SecondTable S ON F.[Date] BETWEEN S.ExchangeRateDate AND ISNULL(S.ExchangeRateDateTo, '99991231')

COALESCE更具可移植性,但在数据类型优先级方面有副作用。

将9991231存储为ExchangeRateDateTo日期是可以接受的:可能不是“正确”但它简化了代码和JOIN。

编辑:要解决不正确的范围,请使用非包容性比较

假设FromDate是范围的开始......

FROM
    FirstTable F
    JOIN
    SecondTable S ON F.[Date] >= S.ExchangeRateDate AND
                     F.[Date] < ISNULL(S.ExchangeRateDateTo, '99991231') 

更改为><=,以便在需要时更加混乱

答案 1 :(得分:0)

对于ExchangeRateDateTo比较,只需使用:

COALESCE(ExchangeRateDateto, GETDATE())

...如果日期字段为NULL,则会检查非NULL日期或当前日期。