避免SQL中的嵌套子查询
我有一个SQL表,其中包含以下格式的数据: Id int 事件时间日期时间 当前值int 对于给定的id,该表可能有多行,这些行表示随着时间的推移值发生的更改,EventTime标识值更改的时间 给定一个特定的时间点,我希望能够计算每个给定值的不同ID的计数 现在,我正在使用一个嵌套子查询和一个临时表,但它似乎可以更有效避免SQL中的嵌套子查询,sql,sql-server,join,Sql,Sql Server,Join,我有一个SQL表,其中包含以下格式的数据: Id int 事件时间日期时间 当前值int 对于给定的id,该表可能有多行,这些行表示随着时间的推移值发生的更改,EventTime标识值更改的时间 给定一个特定的时间点,我希望能够计算每个给定值的不同ID的计数 现在,我正在使用一个嵌套子查询和一个临时表,但它似乎可以更有效 SELECT [Id], ( SELECT TOP 1 [CurrentValue] FROM [ValueHistory]
SELECT [Id],
(
SELECT
TOP 1 [CurrentValue]
FROM [ValueHistory]
WHERE [Ids].[Id]=[ValueHistory].[Id] AND
[EventTime] < @StartTime
ORDER BY [EventTime] DESC
) as [LastValue]
INTO #temp
FROM [Ids]
SELECT [LastValue], COUNT([LastValue])
FROM #temp
GROUP BY [LastValue]
DROP TABLE #temp
这是我的第一步:
select ids.Id, count( distinct currentvalue)
from ids
join valuehistory vh on ids.id = vh.id
where vh.eventtime < @StartTime
group by ids.id
但是,我不确定我是否非常清楚地理解了您的表模型,或者您试图解决的具体问题
这将是:每个Id在特定日期之前的valuehistory的不同“currentvalues”
这就是你想要的吗?我想我理解你的问题 您想获取每个id的最新值,按该值分组,然后查看有多少id具有相同的值?这是正确的吗 如果是这样,这是我的第一次尝试:
declare @StartTime datetime
set @StartTime = '20090513'
select ValueHistory.CurrentValue, count(ValueHistory.id)
from
(
select id, max(EventTime) as LatestUpdateTime
from ValueHistory
where EventTime < @StartTime
group by id
) CurrentValues
inner join ValueHistory on CurrentValues.id = ValueHistory.id
and CurrentValues.LatestUpdateTime = ValueHistory.EventTime
group by ValueHistory.CurrentValue
但不能保证这实际上更快—要使其以任何合适的速度运行,您需要在EventTime上创建索引。让我们记住,因为SQL语言描述的是您想要什么,而不是如何获得它,有许多表达查询的方法,好的查询优化器最终会将这些方法转换为相同的查询执行计划。当然,好的程度取决于您使用的数据库 通常,子查询只是描述连接的一种语法上不同的方式。查询优化器将认识到这一点,并尽其所知确定执行查询的最佳方式。可以根据需要创建临时表。因此,在许多情况下,重新处理查询对您的实际执行时间没有任何影响-最终可能会得到相同的查询执行计划 如果要尝试优化,则需要通过对查询进行描述来检查查询计划。确保它没有对大型表进行全表扫描,并尽可能选择适当的索引。如果并且仅当它在这里做出次优选择时,您应该尝试手动优化查询 话虽如此,您粘贴的查询并不完全符合您为每个给定值计算不同ID计数的既定目标。所以,如果我没有完全回答您的需要,请原谅我,但这里有一些东西需要针对您当前的查询进行测试。语法是近似的,对不起-离开我的桌子
SELECT [IDs].[Id], vh1.[CurrentValue], COUNT(vh2.[CurrentValue]) FROM
[IDs].[Id] as ids JOIN [ValueHistory] AS vh1 ON ids.[Id]=vh1.[Id]
JOIN [ValueHistory] AS vh2 ON vh1.[CurrentValue]=vh2.[CurrentValue]
GROUP BY [Id], [LastValue];
请注意,如果您愿意接受性能影响以更新操作,那么通过添加索引使这些连接达到最佳状态,您可能会看到比重新处理查询更好的性能提高。Good query,但我不认为子查询只是描述联接的一种语法上不同的方式。您也可以在这里分组ValueHistory.EventTimt,并在select中显示它。