我想根据表格中的日期范围选择数据,并在该日期范围之前获取最新值。
如何提高效率?
该表定义为:
Name varchar(100) Checked
DataType varchar(100) Checked
Time datetime Checked
Value int Checked
该表包含以下数据:
Name DataType Time Value
Name1 Type1 2010-09-29 17:29:00.000 999
Name2 Type2 2013-11-02 06:51:00.000 0
我创建了以下查询,这个查询有点长,但确实会返回正确的结果。但是,我想知道是否可以使用更好的T-SQL实现这一目标?
我将在我的应用程序中将代码编写为内联SQL
DECLARE @effectiveFrom DATETIME
SET @effectiveFrom = '2010-09-29 17:30:00'
DECLARE @effectiveTo DATETIME
SET @effectiveTo = '2010-09-29 17:49:00'
DECLARE @bmunit varchar(100)
DECLARE @datatype varchar(100)
--Select * from [Table]
--where (Time >= '2010-09-29 17:30:00' and Time < '2010-09-29 17:49:00')
--union Select top 1 * from [Table]
-- where Time < '2010-09-29 17:30:00' order by Time desc
SELECT P1.[Name]
,P1.[DataType]
,P1.[Time]
,P1.[Value]
,P1.Que
FROM
(
SELECT [Name]
,[DataType]
,[Time]
,[Value]
, 'between' AS [Que]
FROM [Table]
WHERE Time >= @effectiveFrom AND EffectiveTime < @effectiveTo
) P1
UNION SELECT P2.[Name]
,P2.[DataType]
,P2.[Time]
,P2.[Value]
, 'before' AS [Que]
FROM
(
SELECT TOP 1 [Name]
,[DataType]
,Time]
,[Value]
FROM [Table] P1
WHERE Time < @effectiveFrom
) P2 --ON P1.[Name] = P2.[Name] AND P1.[DataType] = P2.[DataType]
WHERE Name = 'MyName' --AND P1.Time >= @effectiveFrom AND P1.Time < @effectiveTo
ORDER BY 2,3
答案 0 :(得分:2)
你应该能够把它削减到类似的东西:
SELECT P1.[Name]
,P1.[DataType]
,P1.[Time]
,P1.[Value]
,'between' AS Que
FROM [Table] P1
WHERE Time >= @effectiveFrom AND Time < @effectiveTo
AND Name = 'MyName'
UNION ALL
SELECT * FROM (
SELECT TOP 1 P2.[Name]
,P2.[DataType]
,P2.[Time]
,P2.[Value]
,'before' AS [Que]
FROM [Table] P2
WHERE Time < @effectiveFrom
AND Name = 'MyName'
ORDER BY 3
) A
如果您不喜欢重复名称检查,那么选择会变得更大:
SELECT * FROM (
SELECT P1.[Name]
,P1.[DataType]
,P1.[Time]
,P1.[Value]
,'between' AS Que
FROM [Table] P1
WHERE Time >= @effectiveFrom AND Time < @effectiveTo
UNION ALL
SELECT * FROM (
SELECT TOP 1 P2.[Name]
,P2.[DataType]
,P2.[Time]
,P2.[Value]
,'before' AS [Que]
FROM [Table] P2
WHERE Time < @effectiveFrom
ORDER BY 3
) A
) B
WHERE Name = 'MyName'
如果你想缩短它,你可以尝试这个,但我认为它不太可读:
SELECT P1.[Name]
,P1.[DataType]
,P1.[Time]
,P1.[Value]
,(CASE WHEN Time >= @effectiveFrom THEN 'between' ELSE 'before' END) AS Que
FROM [Table] P1
WHERE Name = 'MyName'
AND
(
(Time >= @effectiveFrom AND Time < @effectiveTo)
OR (Time < @effectiveFrom AND NOT EXISTS (SELECT *
FROM [Table] P2
WHERE Time < @effectiveFrom
AND P2.Time > P1.Time)
)
)
它更短吗?