所以,我有一个观点,即不能很好地编入索引,而且我无能为力。
该视图的数据看起来有点像this question中的那个,但我的问题基本上与他们的问题相反,我不确定他们的解决方案是否适用于此,尽管类似的TVF或CTE很可能在预测中。
我的数据目前看起来像这样:
CustomPollerAssignmentId DateTime Status
[Some Id B] 2013-11-18 08:54:00 IDLE
[Some Id A] 2013-11-18 08:54:00 DORMANT
[Some Id B] 2013-11-18 08:53:00 IDLE
[Some Id A] 2013-11-18 08:53:00 NOMINAL
与其他问题不同,我需要看到状态没有改变。该视图包含三个单独的表。一个包含十分钟统计数据,一个包含十五分钟统计数据(三到六个月前),另一个包含每小时统计数据(一年前)(
)。此处的目标是检查哪些调制解调器已空闲至少在过去10分钟。我们有大约1200个活动调制解调器,所以这可能多达12000行,这就是为什么我不想用C#做这个,但我仍然是SQL和基于集合思维的新手。我目前正在使用SQL Server 2012的一个实例,但它在这里很新,而且我对使用较新的窗口函数并不熟悉,因为我们在2008R2直到大约一个月之前。
说实话,我甚至不确定从哪里开始,因为我的OOP背景要求我只抓住每个的TOP 10状态并循环。如果全部10 ==空闲||休眠,添加到结果集,但我知道在SQL中必须有更好的方法。有人能指出我正确的方向吗?
修改
试着澄清一下:
我正在使用T-SQL。
这不像WHERE NOT EXISTS子句那么简单。
无论状态是否已更改,除非已取消激活,否则应存在远程状态的条目。这意味着它可以具有最后10分钟的(空闲,空闲,空闲,空闲,空闲,标称,空闲,空闲,空闲,空闲)状态,并且该示例是我不想要包括的情况。结果集应仅包括那些在过去10分钟内只有闲置或休眠状态的遥控器。如果最后一个状态超过三个月,则只有一个状态,间隔为十五分钟。
答案 0 :(得分:1)
如果我理解你的要求:
SELECT [theView].CustomPollerAssignmentId
FROM
[theView]
LEFT JOIN
(
SELECT CustomPollerAssignmentId, MAX([DateTime]) AS LastTime
FROM [theView]
WHERE [Status] <> 'IDLE' AND [DateTime] <= @Now
GROUP BY CustomPollerAssignmentId
) AS NotIdleStatus ON
[theView].CustomPollerAssignmentId = NotIdleStatus.CustomPollerAssignmentId
WHERE
[theView].[DateTime] <= @Now AND
[theView].[Status] = 'IDLE' AND
(
[theView].[DateTime] > NotIdleStatus.LastTime OR
NotIdleStatus.LastTime IS NULL
)
GROUP BY [theView].CustomPollerAssignmentId
HAVING MIN([theView].[DateTime]) <= DATEADD(MINUTE, -10, @Now)
这里的概念是
以下代码选择每个ID的最后一次非空闲时间:
SELECT CustomPollerAssignmentId, MAX([DateTime]) AS LastTime
FROM [theView]
WHERE [Status] <> 'IDLE' AND [DateTime] <= @Now
GROUP BY CustomPollerAssignmentId
我们正在使用LEFT JOIN
,以便仍然捕获任何IDLE但从未处于任何其他状态的状态。 ON
子句通过ID连接它们。
以下代码选择空闲且在当前时间之前的代码:
WHERE
[theView].[DateTime] <= @Now AND
[theView].[Status] = 'IDLE' AND ...
以下代码按ID对记录进行分组,并选择最早时间早于当前时间前10分钟的ID:
GROUP BY [theView].CustomPollerAssignmentId
HAVING MIN([theView].[DateTime]) <= DATEADD(MINUTE, -10, @Now)
此外,您需要传递@Now
值,这是您要检查的当前时间。
答案 1 :(得分:0)
SELECT v1.*
FROM (
SELECT *
FROM vdata
WHERE OnlineStatus IN ('IDLE', 'DORMANT')
) v1
WHERE NOT EXISTS (
SELECT 1
FROM vdata v2
WHERE v2.ModemId = v1.ModemId
AND v2.MinuteMarker > v1.MinuteMarker
AND v2.MinuteMarker <= DATEADD(MINUTE, 10, v1.MinuteMarker )
AND v2.OnlineStatus NOT IN ('IDLE', 'DORMANT')
)