我有一个SQL表,其中包含以下格式的数据:
Id int EventTime dateTime CurrentValue 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
答案 0 :(得分:1)
这是我的第一次去:
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的不同“当前值”。
这就是你要找的东西吗?
答案 1 :(得分:1)
我想我理解你的问题。
您希望获取每个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的索引。
答案 2 :(得分:0)
让我们记住,因为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];
请注意,通过添加索引以使这些连接优于重新执行查询,您可能会看到更好的性能提升,假设您愿意将性能命中更新为更新操作。