也许您可以尝试对所有比更新更早的更新进行排名,一个帐户的状态为 2,按时间戳降序排列。检查是否存在状态为 1 和等级为 1 的此类条目,以了解相应的较年轻的更新确实将状态从 1 更改为 2。
SELECT *
FROM elbat t1
WHERE t1.account_status = 2
AND EXISTS (SELECT *
FROM (SELECT rank() OVER (ORDER BY t2.updated_date DESC) r,
t2.account_status
FROM elbat t2
WHERE t2.account_id = t1.account_id
AND t2.updated_date <= t1.updated_date) x
WHERE x.account_status = 1
AND x.r = 1);
然后,要获取您的小时数,可以创建一个表变量并用一周的小时数填充它(除非您已经有合适的日历/时间表)。然后INNER JOIN 该表(变量)从上面得到结果。由于它是 INNER JOIN 小时,不存在状态更新,因此不会出现在结果中。
DECLARE @current_time datetime = getdate();
DECLARE @current_hour datetime = dateadd(hour,
datepart(hour,
@current_time),
convert(datetime,
convert(date,
@current_time)));
DECLARE @hours
TABLE (hour datetime);
DECLARE @interval_size integer = 7 * 24;
WHILE @interval_size > 0
BEGIN
INSERT INTO @hours
(hour)
VALUES (dateadd(hour,
-1 * @interval_size,
@current_hour));
SET @interval_size = @interval_size - 1;
END;
SELECT *
FROM @hours h
INNER JOIN (SELECT *
FROM elbat t1
WHERE t1.account_status = 2
AND EXISTS (SELECT *
FROM (SELECT rank() OVER (ORDER BY t2.updated_date DESC) r,
t2.account_status
FROM elbat t2
WHERE t2.account_id = t1.account_id
AND t2.updated_date <= t1.updated_date) x
WHERE x.account_status = 1
AND x.r = 1)) y
ON convert(date,
y.updated_date) = h.convert(date,
h.hour)
AND datepart(hour,
y.updated_date) = datepart(hour,
h.hour);
如果您经常使用它和/或性能很重要,您可以考虑为 convert(...) 和 datepart(...) 表达式引入持久、计算和索引列,并在查询中使用它们。索引日历/时间表和子查询中使用的列也值得考虑。
(免责声明:由于您没有提供表格的 DDL 或任何示例数据,因此完全未经测试。)