上周更新记录

时间:2018-07-20 20:12:47

标签: sql sql-server

我正在构建一个报告,该报告需要显示在上周每小时有多少用户从帐户状态1升级到帐户状态2(并删除升级为0的小时数)。我的表的日期已更新,但是不能确定帐户状态是否为正在更新的项目(可能是联系方式等)。

我正在使用的基本表配置如下。还有其他列,但我的查询不需要它们。

帐户ID,帐户状态,更新日期。

我最初的想法是首先过滤并查看当前一周的数据,然后查找它们是否在account_status = 1以及后来在account_status = 2处。

解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

这是您将要使用SELF JOIN的事情。在不获取任何示例数据的情况下,很难确切地说出如何执行此操作,但是希望您至少可以在此基础上进行构建。关于如何编写成功的自我联接的教程很多,因此,如果您遇到困难,我将参考这些指南。

select a.account_id
from tableName a, tableName b
where a.account_id= b.account_id
and
(a.DateModified > 'YYYY-MM-DD' and a.account_status = 1)
and 
(b.DateModified < 'YYYY-MM-DD' and b.account_status= 2)

答案 1 :(得分:0)

也许您可以尝试对所有更新进行排序,而不是对所有更新进行排名,并且时间戳记的状态为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或任何示例数据,因此完全未经测试。)