【问题标题】:Iterate table rows in bigQuery在 bigQuery 中迭代表行
【发布时间】:2021-05-12 19:07:56
【问题描述】:

我正在评估 bigQuery。我有一张桌子,可以记录我们员工的动作。

Table (location_history):

emp String
lat String
lng String
district String
timestamp timestamp

示例:

emp  | lat     | lng    | district| timestamp
------------------------------------------------          
emp1 | 100.234 | 99.456 | ABC  | 2021-02-09 03:00:00
emp1 | 100.234 | 99.456 | XYZ  | 2021-02-09 04:00:00
emp1 | 100.234 | 99.456 | ABC  | 2021-02-09 05:00:00
emp1 | 100.234 | 99.456 | XYZ  | 2021-02-09 06:00:00
emp1 | 100.234 | 99.456 | XYZ  | 2021-02-09 07:00:00
emp1 | 100.234 | 99.456 | ABC  | 2021-02-09 08:00:00
emp1 | 100.234 | 99.456 | WWW  | 2021-02-09 09:00:00

注意:这是每个员工在地区内的移动。员工可以按照时间戳以外的顺序从一个地区移动到另一个地区。此外,即使是一个地区,也可能有数百个重复(相同)的行,因为我们捕获了每个 lng,lat(地区是一个多边形,superArea)。

我需要跟踪访问每个地区的每位员工的历史记录。所以我可以知道哪个员工整天在哪个区。这可以是整个月的轨道。我们在上表中得到的行(每天)超过 1000 亿。

两个问题:

  1. 在任何存储过程(不管任何数据库)中处理大量行是否是个好主意?与语言相比,SP 的性能因素是什么(像 java 这样的服务器端,如果忽略获取和插入,而只关注迭代或操作行/结果集)
  2. BigQuery 是否允许对行进行迭代(从表中使用 select 语句)?否则会有什么解决方案?

提前致谢。

更新: 预期结果是计算员工在每个地区花费的时间。流程将执行:

  1. 查询以使用 (select * from location_history order by emp,district) 获取行
  2. 然后遍历每一行 cox 每隔一行依赖于前一行来计算在特定区域花费的时间

更新 2: 这应该分别计算每个员工的持续时间(将它们分组),而不是根据其他员工活动进行计算。因此,每个员工的每个第一个活动都将具有空/零持续时间,如果找到的下一个活动将从前一行进行计算。希望这是有道理的。

【问题讨论】:

  • 您能否提供一个您希望从您提供的源数据示例中获得的结果示例(表格、报告等)?
  • 我不确定我是否了解存储过程与您的目标之间的关系。为什么,为什么,你需要它?
  • 为什么需要遍历行?
  • @al-dann 感谢您的回复。实际上,我在外部语言 cox 上关联了 SP,我想知道一种语言可以提供的迭代速度与 SP 迭代相比。加上这种顺序计算的准确解决方案应该是什么。我已经更新了我的问题

标签: sql database stored-procedures google-cloud-platform google-bigquery


【解决方案1】:

以下是 BigQuery 标准 SQL

select emp, district, date,
  datetime_diff(
    date, 
    lag(date) over(partition by emp order by date), 
    minute
  ) minutes_in_district
from `project.dataset.table`    

如果应用于您问题中的样本数据 - 输出是

我假设您的日期列是 DATETIME 数据类型 如果它是 TIMESTAMP 数据类型 - 你应该使用 timestamp_diff 函数而不是 datetime_diff

【讨论】:

  • 您能否参考任何好的资源来学习这些用于 bigQuery 的棘手概念,例如分区、窗口、分析函数等?
  • 如何对每个员工进行上述计算??这样每个员工的每一次第一次出现都将为空,然后开始计算。不得混用其他员工的时间
  • 它已经以这种方式工作 - 因为partition by emp part
【解决方案2】:

你无法比较所有数据库引擎的存储过程。每一种都有自己的特点。无论如何,对于大查询,处理大量数据不是问题,只要你有钱支付!

关于语言的处理,这是一个见仁见智的问题。对我来说,如果你是一个铁杆开发者并且你管理所有的优化技巧,你可以构建像内置数据库一样高效的东西。数据库引擎经过优化,可以有效地处理数据集,对它们进行排序,对它们进行索引(...)。此外,留在数据库中,您不会浪费网络时间将数据导出到另一个系统进行处理。

正如 Google 所说,“如果您可以用 SQL 描述您的操作数据,BigQuery 将总是比其他数据流或 Dataproc 更快、更便宜”。但是,BigQuery 无法执行外部 API 调用。如果是您的用例,您需要在 BigQuery 之外处理数据

关于第二点,BigQuery 提出了Analytics function,我认为您正在寻找这个。如果您在构建请求时需要帮助,能否提供预期结果的示例?


编辑 1

如果您尝试此查询(使用您的样本数据进行测试)

with data as (
select "emp1" as emp, 100.234 as log, 99.456 as lat, "ABC" as district, ("2021-02-09 03:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "XYZ" as district, ("2021-02-09 04:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "ABC" as district, ("2021-02-09 05:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "XYZ" as district, ("2021-02-09 06:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "XYZ" as district, ("2021-02-09 07:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "ABC" as district, ("2021-02-09 08:00:00") as date 
UNION ALL
select "emp1" as emp, 100.234 as log, 99.456 as lat, "WWW" as district, ("2021-02-09 09:00:00") as date
)
select emp, date, district as current_distinct, LAG(district) over (ORDER by date) as prev_district from data

你可以得到这个结果:

emp     date                    current_distinct    prev_district
emp1    2021-02-09 03:00:00     ABC 
emp1    2021-02-09 04:00:00     XYZ                  ABC
emp1    2021-02-09 05:00:00     ABC                  XYZ
emp1    2021-02-09 06:00:00     XYZ                  ABC
emp1    2021-02-09 07:00:00     XYZ                  XYZ
emp1    2021-02-09 08:00:00     ABC                  XYZ
emp1    2021-02-09 09:00:00     WWW                  ABC

【讨论】:

  • 感谢您的回复。实际上我的场景是遍历行,每一行取决于前一行员工,看看他在特定地区花了多少时间。为此,我想知道是否应该编写一个 SP 或简单的 JDBC(批处理)来处理每一行。
  • 我的编辑对您有帮助吗?是你所期望的吗?
  • 可以有千区
  • 然后呢?你想达到什么目标?最后你期待什么?
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-13
相关资源
最近更新 更多