选择日期范围之外的历史记录

时间:2013-08-16 22:04:45

标签: sql select sql-server-2012 date-range

我有一种情况需要从地址历史记录表中选择一个特定日期和时间的当前地址。一些样本记录可能如下:

地址/客户端JOIN表(Address_Client_JOIN):

-------------------------
|AddressId  |  ClientId |   
-------------------------
|5          |  8888887  | 
-------------------------
|6          |  8888887  |
-------------------------

历史表(Address_History):

-------------------------------------------------------------------------------------------
|HistoryId | AddressId | AddTypeId | StreetAddress  |  CreatedDate      |   ModifiedDate  |
-------------------------------------------------------------------------------------------
|1         |     5     |     1     | 123 Home Street|  2013-03-11 21:08 | 2013-04-02 13:18|
-------------------------------------------------------------------------------------------
|2         |     5     |     2     | 456 My Avenue  |  2013-03-11 21:08 | 2013-04-08 15:00|
-------------------------------------------------------------------------------------------
|3         |     6     |     1     | 789 Cat Road   |  2013-05-17 12:00 | 2013-05-17 12:00|
-------------------------------------------------------------------------------------------

此查询的要求是我必须获取@dateOfService介于CreatedDate和ModifiedDate之间的最早记录,其中AddTypeId为“1”(如果有),否则为任何其他AddTypeId。我到目前为止创建的查询是:

SELECT TOP 1 ah.HistoryId, ah.AddTypeId, ah.AddressId, ah.StreetAddress,
ah.CreatedDate, ah.ModifiedDate 
FROM Address_Client_JOIN acj WITH (NOLOCK)
INNER JOIN Address_History ah WITH (NOLOCK) ON ah.AddressId = acj.AddressId
WHERE apj.ClientId = @clientId 
    AND (ah.CreatedDate <= @dateOfService 
        AND (@dateOfService <= ah.ModifiedDate ))
ORDER BY 
    ah.HistoryId ASC, CASE WHEN ah.AddTypeId = 1 THEN 0 ELSE 1 END

只要@dateOfService介于CreatedDate和ModifiedDate之间,这就可以正常工作。但是,当我在ModifiedDate之后出现@dateOfService时,显然我什么都没得到。我需要能够解决(使用上述数据)@dateOfService在2013年5月17日的ModifiedDate之后的情况。例如,@ dateOfService ='2013-08-01 12:30'。

提前致谢。

1 个答案:

答案 0 :(得分:0)

您只选择最上一行。这意味着您可以将where过滤器移动到order by子句中。然后,它成为优先事项而不是过滤器。

因此,如果没有任何内容与过滤器匹配,您仍然可以获得一行。我认为你想要的查询是这样的:

SELECT TOP 1 ah.HistoryId, ah.AddTypeId, ah.AddressId, ah.StreetAddress,
       ah.CreatedDate, ah.ModifiedDate 
FROM Address_Client_JOIN acj WITH (NOLOCK) INNER JOIN
     Address_History ah WITH (NOLOCK)
     ON ah.AddressId = acj.AddressId
WHERE apj.ClientId = @clientId
ORDER BY ah.HistoryId ASC,
         (CASE WHEN ah.AddTypeId = 1 THEN 0 ELSE 1 END),
         (case when ah.CreatedDate <= @dateOfService AND @dateOfService <= ah.ModifiedDate then 1
               when @dateOfService > ah.ModifiedDate then 2
               else 3
          end)