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