简单的SQL查询以获取给定日期的值

时间:2012-01-18 17:31:22

标签: sql sql-server

我在SQL中有这个简单的问题。我有一个有4列的表。列是ID,DateTime,Decimal,AnotherID。

DECLARE @data DATETIME 
SET @data = '20120101'

SELECT [ID]
      ,[Data]
      ,[Value]
      ,[InID]   
 FROM [dbo].[Static] 
 WHERE InID = 1 AND [Data] <= @data

现在我必须根据InID和数据选择合适的值。 InID可以有多个具有不同日期的行。这是InID = 1的示例输出。

ID          Data            Value              InID
389         2012-01-02      10.00000000     1
390         2011-12-16      20.00000000     1
391         2011-12-13      15.00000000     1

现在基于InIDData我需要在给定日期获得Value。例如,对于InID = 1我需要Value2011-12-14。当然,价值应该来自13th of December,如果我问它关于日期2012-01-13的价值,它应该取最后一个值。但是,如果问题是关于第一个日期之前的日期,则应该返回NULL。我尝试了多种组合,但我的大脑似乎是无序的,所以任何帮助都会受到赞赏。

5 个答案:

答案 0 :(得分:4)

尝试此选项仅获取受Value参数约束的最新@data

SELECT TOP 1 [Value]
FROM [dbo].[Static] 
WHERE InID = 1 AND [Data] <= @data
ORDER BY [Data] DESC;

对于问题的最后一部分,如果您需要NULL结果,则必须将查询包装在上面,因为如果没有资格,它将返回空结果集:

DECLARE @theValue float;
SELECT @theValue = (
  SELECT TOP 1 [Value]
  FROM [dbo].[Static] 
  WHERE InID = 1 AND [Data] <= @data
  ORDER BY [Data] DESC
);

最近的就是这个(只要知道它可以抓住未来或过去的日期):

 SELECT TOP 1 [Value]
 FROM [dbo].[Static]
 WHERE InID = 1
 ORDER BY ABS(DATEDIFF(Day, [Data], @data));

答案 1 :(得分:2)

我不知道这有多高效,但它应该有用......

-- Some other commands here, that MUST be terminated with a ;
-- It's anal, but that's how MS implemented the WITH syntax

WITH
  sequenced_data AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY InID ORDER BY ABS(DATEDIFF(day, @yourDate, Data)) ASC) AS sequence_id,
    *
  FROM
    static
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1

修改

这就是我原来的......

它提供了The nearest date down

;WITH
  sequenced_data AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY InID ORDER BY Data DESC) AS sequence_id,
    *
  FROM
    static
  WHERE
    Data <= @yourDate
)
SELECT
  *
FROM
  sequenced_data
WHERE
  sequence_id = 1

答案 2 :(得分:2)

SELECT TOP 1
       [ID]
      ,[Data]
      ,[Value]
      ,[InID]   
 FROM [dbo].[Static] 
 WHERE InID = 1 AND [Data] <= @data
ORDER BY DATA desc

如果行不存在,您可以在所有字段中使用NULL吗?

答案 3 :(得分:1)

这应该根据最高限定日期记录为您提供一行的所有值。唯一的问题是,如果您在同一日期有多个条目,并且“InID”= 1.如果数据字段实际上是日期/时间精度(只是简化了您的发布样本),那么您将获得更好的精度。我会确保InID和Data的索引能够更好地进行优化。

select
      Static.*
   from
      ( select max( Data ) as HighestQualifiedDate
           from Static
          where InID = 1
            and Data <= @data ) PreQuery
      JOIN Static
         on InID = 1
         AND PreQuery.HighestQualifiedDate = Static.Data

答案 4 :(得分:0)

SELECT TOP 1 
    [Value]
FROM
  ( SELECT TOP 1  
        [Data], [Value]
    FROM [dbo].[Static] 
    WHERE InID = 1 AND [Data] <= @data
    ORDER BY [Data] DESC
  UNION ALL
    SELECT TOP 1 
        [Data], [Value]
    FROM [dbo].[Static] 
    WHERE InID = 1 AND [Data] >= @data
    ORDER BY [Data] ASC
  UNION ALL
    SELECT 
        DATEADD(day, -1, MIN([Data])), NULL
    FROM [dbo].[Static] 
    WHERE InID = 1 
  ) AS tmp
ORDER BY ABS(DATEDIFF(Day, [Data], @data))