如何进行滚动求和,每一行需要包含前几行的总和

2024-01-21

我有桌子[访问]。当 order_number 为空时,我需要获取按 user_id 分组的行以及 Visit_duration_seconds 的总和,例如,对于用户 [2875636],我将得到:61+151+33+13。每行应包含其前面的行的总和。
请参阅下面预期结果中的 RESULT 列

user_id   starttime           visit_duration_seconds  order_number
2875636   2013-01-16 18:03:50 61  
2875636   2013-01-16 18:08:18 151 
2875636   2013-01-16 18:15:43 33  
2875636   2013-01-16 18:16:37 13  
2875636   2013-01-16 18:18:01 2011                     10177888
2875636   2013-01-16 18:24:35 1172                     10177884
2875636   2013-01-16 18:32:03 4731    
2875636   2013-01-16 18:33:27 407 
2875636   2013-01-16 18:37:29 74  
2875636   2013-01-16 18:48:55 80  
2875636   2013-01-16 19:05:00 1955    
2875636   2013-01-16 19:14:12 326 
2875636   2013-01-16 19:23:39 972 
2875636   2013-01-16 19:33:05 5440    
2875636   2013-01-16 19:35:48 43  
2875636   2013-01-16 19:41:10 66  
2875636   2013-01-16 19:42:03 100 
2875636   2013-01-16 19:42:12 2414                     10177940
2875636   2013-01-16 19:49:05 432                  10177925
2875636   2013-01-16 19:50:19 183 
2875636   2013-01-16 19:52:46 2061    
2875636   2013-01-16 19:52:53 400 
2875636   2013-01-16 20:00:47 338 
2875636   2013-01-16 20:08:58 216 
2875636   2013-01-16 20:14:21 58  
2875636   2013-01-16 20:14:26 196 
2875636   2013-01-16 20:19:14 2189    
2875636   2013-01-16 20:21:29 424 
2875636   2013-01-16 20:24:42 999 
2875636   2013-01-16 21:01:39 1810    
2875636   2013-01-16 21:02:54 525 
2875636   2013-01-16 21:10:06 27  
2875636   2013-01-16 21:12:08 282 
2875636   2013-01-16 21:51:02 6   
2875636   2013-01-16 22:18:34 173 
2875636   2013-01-16 23:02:58 318 
2875636   2013-01-16 23:45:37 207 
3018868   2013-01-16 16:01:45 18  
3018868   2013-01-16 16:16:45 39  
3018868   2013-01-16 16:22:55 656 
3018868   2013-01-16 16:25:54 1852    
3018868   2013-01-16 16:29:23 688 
3018868   2013-01-16 16:47:26 2258                       10177846
3018868   2013-01-16 16:57:41 572 
3018868   2013-01-16 17:06:47 1431    
3018868   2013-01-16 17:18:32 29  
3018868   2013-01-16 17:21:57 45  
3018868   2013-01-16 17:29:23 16  
3018868   2013-01-16 17:36:47 490

预期结果

user_id starttime           visit_duration_seconds  order_number        RESULT
2875636 2013-01-16 18:03:50 61                                      61
2875636 2013-01-16 18:08:18 151                                     212
2875636 2013-01-16 18:15:43 33                                      245
2875636 2013-01-16 18:16:37 13                                      258
2875636 2013-01-16 18:18:01 2011                     10177888           0
2875636 2013-01-16 18:24:35 1172                     10177884           0
2875636 2013-01-16 18:32:03 4731                                        4731
2875636 2013-01-16 18:33:27 407                                     5138
2875636 2013-01-16 18:37:29 74                                      5212
2875636 2013-01-16 18:48:55 80                                      ...
2875636 2013-01-16 19:05:00 1955                                        ...
2875636 2013-01-16 19:14:12 326                                     ...
2875636 2013-01-16 19:23:39 972 
2875636 2013-01-16 19:33:05 5440    
2875636 2013-01-16 19:35:48 43  
2875636 2013-01-16 19:41:10 66  
2875636 2013-01-16 19:42:03 100 
2875636 2013-01-16 19:42:12 2414                     10177940
2875636 2013-01-16 19:49:05 432                  10177925
2875636 2013-01-16 19:50:19 183 
2875636 2013-01-16 19:52:46 2061    
2875636 2013-01-16 19:52:53 400 
2875636 2013-01-16 20:00:47 338 
2875636 2013-01-16 20:08:58 216 
2875636 2013-01-16 20:14:21 58  
2875636 2013-01-16 20:14:26 196 
2875636 2013-01-16 20:19:14 2189    
2875636 2013-01-16 20:21:29 424 
2875636 2013-01-16 20:24:42 999 
2875636 2013-01-16 21:01:39 1810    
2875636 2013-01-16 21:02:54 525 
2875636 2013-01-16 21:10:06 27  
2875636 2013-01-16 21:12:08 282 
2875636 2013-01-16 21:51:02 6   
2875636 2013-01-16 22:18:34 173 
2875636 2013-01-16 23:02:58 318 
2875636 2013-01-16 23:45:37 207 
3018868 2013-01-16 16:01:45 18  
3018868 2013-01-16 16:16:45 39  
3018868 2013-01-16 16:22:55 656 
3018868 2013-01-16 16:25:54 1852    
3018868 2013-01-16 16:29:23 688 
3018868 2013-01-16 16:47:26 2258                       10177846
3018868 2013-01-16 16:57:41 572 
3018868 2013-01-16 17:06:47 1431    
3018868 2013-01-16 17:18:32 29  
3018868 2013-01-16 17:21:57 45  
3018868 2013-01-16 17:29:23 16  
3018868 2013-01-16 17:36:47 490 

您可以利用 MySQL 用户变量来模拟分析函数。 (还有一些其他方法,例如使用半连接或使用相关子查询。如果您认为它们可能更合适,我也可以为这些方法提供解决方案。)

要模拟“运行总计”分析函数,请尝试以下操作:

SELECT t.user_id
     , t.starttime
     , t.order_number
     , IF(t.order_number IS NOT NULL,
         @tot_dur := 0,
         @tot_dur := @tot_dur + t.visit_duration_seconds) AS tot_dur
  FROM visit t
  JOIN (SELECT @tot_dur := 0) d
 ORDER BY t.user_id, t.start_time

这里的“技巧”是使用 IF 函数来测试是否order_number一片空白。当它为空时,我们将持续时间值添加到变量中,否则,我们将变量设置为零。

我们使用内联视图(别名为d,以确保 @tot_dur 变量初始化为零。

注意:像这样使用 MySQL 用户变量时要小心。在上面的 SELECT 语句中,SELECT 列表中的变量赋值发生在 ORDER BY 之后,因此我们可以获得确定性行为。


该查询不处理 user_id 中的“中断”。为此,我们需要前一行中的 user_id 值。我们可以将其保存在另一个用户变量中。操作的顺序是确定的,在覆盖前一行的 user_id 之前,我们需要注意进行累积。

我们需要对列重新排序,以便 user_id 出现在 tot_dur 之后(或者包含 user_id 列的第二个副本)

SELECT t.user_id
     , t.starttime
     , t.order_number
     , IF(t.order_number IS NULL,
         @tot_dur := IF(@prev_user_id = t.user_id,@tot_dur,0) + t.visit_duration_seconds,
         @tot_dur := 0
       ) AS tot_dur
     , @prev_user_id := t.user_id AS prev_user_id
  FROM visit t
  JOIN (SELECT @tot_dur := 0, @prev_user_id := NULL) d
 ORDER BY t.user_id, t.start_time

返回的值在user_id and prev_user_id列是相同的。可以删除该“额外”列,或者可以通过将查询(作为内联视图)包装在另一个查询中来重新排序列,尽管这会带来性能成本:

SELECT v.user_id
     , v.starttime
     , v.order_number
     , v.tot_dur
  FROM (SELECT t.starttime
             , t.order_number
             , IF(t.order_number IS NULL,
                 @tot_dur := IF(@prev_user_id = t.user_id,@tot_dur,0) + t.visit_duration_seconds,
                 @tot_dur := 0
               ) AS tot_dur
             , @prev_user_id := t.user_id AS user_id
          FROM visit t
          JOIN (SELECT @tot_dur := 0, @prev_user_id := NULL) d
         ORDER BY t.user_id, t.start_time
       ) v

该查询表明 MySQL 可以返回指定的结果集。但为了获得最佳性能,我们希望仅在内联视图中运行查询(别名为v),并在检索行时在客户端处理列的重新排序(将 user_id 列放在前面)。

其他两种常见的方法是使用半连接和使用相关子查询,尽管这些方法在处理大型集合时可能会消耗更多资源。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何进行滚动求和,每一行需要包含前几行的总和 的相关文章

  • MySql 视图脚本中的注释

    可以这样做吗 我尝试过多个 gui mysql workbench navicat toad for mysql 但没有一个保存这样的注释 something important select something else importan
  • SQL:如何从一个表中获取另一个表中每一行的随机行数

    我有两个数据不相关的表 对于表 A 中的每一行 我想要例如表 B 中的 3 个随机行 使用光标这相当容易 但速度非常慢 那么我该如何用单个语句来表达这一点以避免 RBAR 呢 要获得 0 到 N 1 之间的随机数 可以使用 abs chec
  • SQL Server 查询中 UNION ALL 与 OR 条件

    我必须根据表上不存在的条件选择一些行 如果我使用如下的 union all 它会在不到 1 秒的时间内执行 SELECT 1 FROM dummyTable WHERE NOT EXISTS SELECT 1 FROM TABLE t WH
  • Ruby ActiveRecord 和 sql 元组支持

    ActiveRecord 是否支持 where 子句中的元组 假设底层数据库支持 结果 where 子句看起来像这样 where name address in John 123 Main St I tried Person where n
  • jdbc4.MySQLSyntaxErrorException:数据库中不存在表

    我正在使用 SpringBoot 开发一个网络应用程序 这是我的application properties文件来指定访问数据库的凭据 spring datasource driverClassName com mysql jdbc Dri
  • 更改表添加列并在同一条件 IF 语句中更新新列

    我正在尝试添加列并在同一 if 语句中更新它 BEGIN TRAN IF NOT EXISTS SELECT 1 FROM sys columns WHERE Name N Code AND Object ID Object ID N Te
  • SQL Server 中离线索引重建和在线索引重建有什么区别?

    重建索引时 有一个选项ONLINE OFF and ONLINE ON 我知道当ONLINE模式打开时 它会复制索引 切换新查询以利用它 然后重建原始索引 使用版本控制跟踪两者的更改 如果我错了 请纠正我 但是 SQL 在离线模式下会做什么
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • SQL查询json字典数据

    我的表中的 CLOB 字段包含 JSON 如下所示 a value1 b value2 c value3 我正在尝试编写一个 SQL 查询来返回一个包含键和值字段的表 如下所示 key value a value1 b value2 c v
  • 使用什么框架来引导我的第一个生产 scala 项目?

    我正在第一次涉足 scala 的生产应用程序 该应用程序当前打包为 war 文件 我的计划是创建 scala 编译工件的 jar 文件 并将其添加到 war 文件的 lib 文件夹中 我的增强功能是通过 Jersey 公开的 mysql 支
  • MySQL InnoDB 约束不起作用

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • Google Cloud SQL 上的故障转移如何运作?

    我打算将 PHP 应用程序 从 Google Cloud Platform 外部的服务器 连接到 Google Cloud SQL 我想知道如何设计应用程序以正确地对其数据库进行故障转移 根据manual https cloud googl
  • 如何将所有父母的父母作为循环引用表中子对象的列?

    我有一个表格 其中有类似的列 entityID entityName parentID 我如何编写一个查询来返回实体的所有父级级别 以返回类似的内容 childentityname parentlevel1name parentlevel2
  • PostgreSQL函数中sql语言和plpgsql语言的区别

    我很新数据库开发所以我对下面的例子有一些疑问 函数 f1 语言 SQL create or replace function f1 istr varchar returns text as select hello varchar istr
  • 如何在 SQL Server 2012 中选择除一列之外的所有列? [复制]

    这个问题在这里已经有答案了 有没有一种方法可以选择所有列 但只选择我不想选择的特定列 我的意思是有时我会遇到这样的问题 表有数百个字段 而我只需要删除一个字段 我需要重写所有列吗 有什么窍门吗 喜欢select
  • 研究MySQL、SQLite源码了解RDBMS实现[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我知道实现数据库是一个很大的话题 但我想通过研究数据库系统的源代码来基本了解数据库系统的工作原理 例如
  • 在 Yii 的标准中如何获得计数 (*)

    我正在尝试构建一个具有以下内容的查询group by属性 我正在尝试得到id和count它一直告诉我count is invalid列名 我怎样才能得到count来自group by询问 工作有别名 伊伊 1 1 11 其他不及格 crit
  • 如何使用 SQL 查询创建逗号分隔的列表?

    我有 3 个表 名为 应用程序 ID 名称 资源 id 名称 应用程序资源 id app id resource id 我想在 GUI 上显示所有资源名称的表格 在每一行的一个单元格中 我想列出该资源的所有应用程序 以逗号分隔 所以问题是
  • 使用 PHP 将 latin1_swedish_ci 转换为 utf8

    我有一个数据库 里面充满了类似的值 Dhaka 应该是 Dhaka 因为我在创建数据库时没有指定排序规则 现在我想修复它 我无法从最初获取数据的地方再次获取数据 所以我在想是否可以在 php 脚本中获取数据并将其转换为正确的字符 我已将数据

随机推荐