避免SQL中的嵌套子查询

避免SQL中的嵌套子查询,sql,sql-server,join,Sql,Sql Server,Join,我有一个SQL表,其中包含以下格式的数据: Id int 事件时间日期时间 当前值int 对于给定的id,该表可能有多行,这些行表示随着时间的推移值发生的更改,EventTime标识值更改的时间 给定一个特定的时间点,我希望能够计算每个给定值的不同ID的计数 现在,我正在使用一个嵌套子查询和一个临时表,但它似乎可以更有效 SELECT [Id], ( SELECT TOP 1 [CurrentValue] FROM [ValueHistory]

我有一个SQL表,其中包含以下格式的数据:

Id int 事件时间日期时间 当前值int

对于给定的id,该表可能有多行,这些行表示随着时间的推移值发生的更改,EventTime标识值更改的时间

给定一个特定的时间点,我希望能够计算每个给定值的不同ID的计数

现在,我正在使用一个嵌套子查询和一个临时表,但它似乎可以更有效

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中显示它。