使用简单的选择查询来查找SQL Server中的日期的问题

时间:2010-03-09 14:56:44

标签: sql sql-server datetime

我使用简单查询来获取某人的合约日期:

SELECT 
    [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3

这就是我得到的:

KlienciUmowyDataPoczatkowa  KlienciUmowyDataKoncowa
2005-11-28 00:00:00.000    2008-07-22 00:00:00.000
2008-07-23 00:00:00.000    2010-03-09 15:45:42.457

客户签署一份合同,该合同始于2005年11月28日,然后签署了附录,以便他的合同在2008-07-22结束,新的合同在2008-07-23开始并持续到今天(转换为NULL当前时间)。可能有许多客户有更多的附录,但一切都是这样。

My question is:我如何得到之间/之间的合约让我们说2008-04-01 - 2008-06-30?那个时期之间的客户可能会有2个甚至5个附录,所以应该返回所有这些附件。

另外我不确定是否需要使用IsNull?也许有一个更好的方法,所以我可以跳过IsNull使用并输入当前日期作为替换。

编辑:

我认为来自marc_s的解决方案解决了它,但似乎没有:

SELECT 
    [KlienciUmowyDataPoczatkowa],
    [KlienciUmowyDataKoncowa]
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
 WHERE  [PortfelID] = 3 AND 
 [KlienciUmowyDataPoczatkowa] <= '2008-07-01' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '2008-09-30'

它会在2008-07-01到2008-09-30期间返回0个日期,当它应该返回时:

2005-11-28 00:00:00.000    2008-07-22 00:00:00.000
2008-07-23 00:00:00.000    NULL

由于客户在两个时间都有合同。

EDIT2:

我测试过提出的2个查询。第一个日期(20080401 - 20080630)如下例所示,第一个查询返回1行(预期),第二个查询返回0行(不是预期的)。

 SELECT [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], '99991231') AS 'KlienciUmowyDataKoncowa'
  FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]     
  WHERE  [PortfelID] = 3  
  AND [KlienciUmowyDataPoczatkowa] <= '20080401' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080630'

 SELECT 
 [KlienciUmowyDataPoczatkowa],
 [KlienciUmowyDataKoncowa]
 FROM   
[BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
 WHERE  
[PortfelID] = 3 AND 
-- either: start date is sometime between the two dates
([KlienciUmowyDataPoczatkowa] BETWEEN '20080401' AND '20080630'
-- or: end date is sometime between the two dates        
  OR 
  ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080401' AND '20080630')

日期'20080701'到'20080930'的第二次测试显示第一次查询0结果(未预期),第二次查询显示2行(预期)。

 SELECT [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], '99991231') AS 'KlienciUmowyDataKoncowa'

 FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]

WHERE  [PortfelID] = 3  

 AND [KlienciUmowyDataPoczatkowa] <= '20080701' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080930'


SELECT 
[KlienciUmowyDataPoczatkowa],
[KlienciUmowyDataKoncowa]

FROM   
[BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  
[PortfelID] = 3 AND 
-- either: start date is sometime between the two dates
([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930'
-- or: end date is sometime between the two dates        
  OR 
  ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930')

EDIT3:

使用两个示例中的COMBINED解决方案,它适用于两个日期。但是,对于不同的客户日期,它不会回击我吗?任何想法?

 SELECT [KlienciUmowyDataPoczatkowa]
     , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
 FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
  AND 
  (
  ([KlienciUmowyDataPoczatkowa] BETWEEN '20080401' AND '20080630'
   OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080401' AND '20080630')
   OR ([KlienciUmowyDataPoczatkowa] <= '20080401' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080630')

  )

SELECT [KlienciUmowyDataPoczatkowa]
 , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
 FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
  AND 
  (
  ([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930'
   OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930')
   OR ([KlienciUmowyDataPoczatkowa] <= '20080701' AND IsNULL([KlienciUmowyDataKoncowa], '99991231') >= '20080930')

  )

4 个答案:

答案 0 :(得分:2)

  

我的问题是:我如何获得合同   我们说之间是活跃的   2008-04-01 - 2008-06-30?这是可能的   那个时期之间的客户   会有2个甚至5个附录所以它   应该归还所有这些。

基本上这意味着:

  • 合约的开始日期必须在2008-04-01或之前。
  • 合同的结束日期必须在2008-06-30之后或之后

所以你需要这样的东西:

SELECT 
    (list of fields)
FROM dbo.YourTable
WHERE
    StartDate <= '20080401' AND EndDate >= '20080630'

(或者波兰语中的任何内容: - )

除非你的某个日期可能为NULL,否则你不需要ISNULL(例如,EndDate = NULL意味着:合同在被撤销之前有效)。

在这种情况下,请执行以下操作:

SELECT 
    (list of fields)
FROM dbo.YourTable
WHERE
    StartDate <= '20080401' AND ISNULL(EndDate, '99991231') >= '20080630'

如果EndDate为NULL,假装它是9999年12月31日 - 那应该是接下来的几千年:)

<强>更新
要获得更新,请在此处尝试此查询:

SELECT 
    [KlienciUmowyDataPoczatkowa],
    [KlienciUmowyDataKoncowa]
FROM   
    [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  
    [PortfelID] = 3 AND 
    -- either: start date is sometime between the two dates
    ([KlienciUmowyDataPoczatkowa] BETWEEN '20080701' AND '20080930'
    -- or: end date is sometime between the two dates        
      OR 
      ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN '20080701' AND '20080930')

这会返回您期望的结果吗?

答案 1 :(得分:1)

我认为这会奏效。如果没有,那么你可以更清楚一些,并给我们一些示例行,以便应该和不应该返回。

SELECT 
    [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
AND KlienciUmowyDataPoczatkowa] <= '2008-04-01'
AND IsNULL([KlienciUmowyDataKoncowa], GETDATE()) >= '2008-06-30'

或者你可以做到

SELECT 
    [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
AND KlienciUmowyDataPoczatkowa] <= '2008-04-01'
AND ([KlienciUmowyDataKoncowa] >= '2008-06-30'
  OR [KlienciUmowyDataKoncowa] IS NULL)

最后,听起来您可能希望在这些日期之间至少有1个有效合同的客户签订所有合同。如果是这样的话:

SELECT 
    [KlienciUmowyDataPoczatkowa],
    IsNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
AND <Client_ID> IN
    (SELECT 
        <Client_ID>
    FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
    WHERE  [PortfelID] = 3
    AND KlienciUmowyDataPoczatkowa] <= '2008-04-01'
    AND IsNULL([KlienciUmowyDataKoncowa], GETDATE()) >= '2008-06-30')

答案 2 :(得分:0)

如果我理解你的问题,我猜你可以使用这样的东西:

SELECT  
    [KlienciUmowyDataPoczatkowa], 
    CASE WHEN [KlienciUmowyDataKoncowa] IS NULL THEN GETDATE() ELSE [KlienciUmowyDataKoncowa] END AS 'KlienciUmowyDataKoncowa' 
FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy] 
WHERE  [PortfelID] = 3 
    AND [KlienciUmowyDataPoczatkowa] BETWEEN @ContractDateStart AND @ContractDateEnd

其中@ContractDateStart和@ContractDateEnd分别是查询的参数化值合约日期开始日期和日期结束。

答案 3 :(得分:0)

这应该让你的所有行在一段时间内开始或结束(注意变量@StartDate和@EndDate)

SELECT [KlienciUmowyDataPoczatkowa]
     , ISNULL([KlienciUmowyDataKoncowa], GETDATE()) AS 'KlienciUmowyDataKoncowa'
 FROM   [BazaZarzadzanie].[dbo].[KlienciPortfeleUmowy]
WHERE  [PortfelID] = 3
  AND ([KlienciUmowyDataPoczatkowa] BETWEEN @StartDate AND @EndDate
   OR ISNULL([KlienciUmowyDataKoncowa], GETDATE()) BETWEEN @StartDate AND @EndDate)