【问题标题】:Update record for the last week上周更新记录
【发布时间】:2018-07-20 20:12:47
【问题描述】:

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

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

account_id、account_status、updated_date。

我最初的想法是首先过滤并查看本周的数据,然后查找它们是否处于 account_status = 1 和之后的 account_status = 2。

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

【问题讨论】:

  • 您的描述没问题,但具有预期结果的格式化示例数据是提出问题的首选方式。
  • 你好,欢迎来到 StackOverflow!作为一条建议,StackOverflow 上最好的问题是那些已经尝试过或就特定问题寻求帮助的问题。就目前而言,您的问题可以解释为请求某人为您编写代码,这有点令人不悦。请花点时间熟悉How do I ask a good question?,并编辑您的问题以包含您自己的尝试,或指定您自己无法完成的部分。

标签: sql sql-server


【解决方案1】:

这就是你会使用 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)

【讨论】:

    【解决方案2】:

    也许您可以尝试对所有比更新更早的更新进行排名,一个帐户的状态为 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 或任何示例数据,因此完全未经测试。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-26
      • 2016-01-28
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多