BigQuery 在选择不同行时按一个字段中的最大值分组

BigQuery group by maximum value in one field while selecting distinct rows

对于每 20 分钟的时间间隔,我试图找到带宽的最大值(下面 table 中的 mbps 列),每个唯一的 IP 地址生成,与相应的端口号。

每个 IP 地址在每 20 分钟内可能会或不会出现超过一次。每次在 20 分钟的时间间隔内记录一个 IP 地址时,列出的端口号可能相同也可能不同。

例如下面table中,ip地址192.168.10.1在12:20中出现了3次,端口号分别为443、80、80。在另一种情况下,IP 地址 192.168.10.2 在 12:40 期间出现两次,相同的端口号 443,列出两次,但 mbps(带宽)列的值不同。

目标是 select 并且只列出每个唯一的 IP 地址一次,对于每个二十分钟的时间段,按 mbps 降序排列。

table根据数据注入的时间进行分区。

我打算编写一个 cron 作业来自动执行此查询。 cron 作业将 运行 每小时,每周 7 天。查询将采用标准 SQL.

原table:

Row time                ip_address          port        mbps

1   01/01/2019 12:20    192.168.10.1        443         100
2   01/01/2019 12:20    192.168.10.1        80          120
3   01/01/2019 12:20    192.168.10.2        80          200
4   01/01/2019 12:20    192.168.10.1        80          110
5   01/01/2019 12:40    192.168.10.2        443         200
6   01/01/2019 12:40    192.168.10.3        443         300
7   01/01/2019 12:40    192.168.10.2        443         200
8   01/01/2019 12:40    192.168.10.1        443         300
9   01/01/2019 13:00    192.168.10.3        443         90
10  01/01/2019 13:00    192.168.10.2        80          100
11  01/01/2019 13:00    192.168.10.1        443         500

执行下面的代码,

#standardSQL
SELECT
  FORMAT_TIMESTAMP("%d/%m/%Y %H:%M", TIMESTAMP_SECONDS, 'Europe/London') AS time,
  ip_address,
  port,
  SUM(bandwidth) AS mbps,
FROM
  dataset1.table1
WHERE
  _PARTITIONDATE = DATE_SUB(CURRENT_DATE(),INTERVAL 0 DAY)  
  AND timestamp > TIMESTAMP_ADD(CURRENT_TIMESTAMP(),INTERVAL -40 MINUTE)
GROUP BY
  time,
  ip_address,
  port
ORDER BY
  time,
  mbps DESC

我明白了 table,

Row time                ip_address          port        mbps

1   01/01/2019 12:20    192.168.10.2        80          200
2   01/01/2019 12:20    192.168.10.1        80          120
3   01/01/2019 12:20    192.168.10.1        80          110
4   01/01/2019 12:20    192.168.10.1        443         100
5   01/01/2019 12:40    192.168.10.1        443         300
6   01/01/2019 12:40    192.168.10.3        443         300
7   01/01/2019 12:40    192.168.10.2        25          200
8   01/01/2019 12:40    192.168.10.2        443         160
9   01/01/2019 13:00    192.168.10.1        443         500
10  01/01/2019 13:00    192.168.10.2        80          100
11  01/01/2019 13:00    192.168.10.3        443         90

这不是我想要的。相反,我想要这个:

Row time                ip_address          port        mbps

1   01/01/2019 12:20    192.168.10.2        80          200
2   01/01/2019 12:20    192.168.10.1        80          120
3   01/01/2019 12:40    192.168.10.1        443         300
4   01/01/2019 12:40    192.168.10.3        443         300
5   01/01/2019 12:40    192.168.10.2        25          200
6   01/01/2019 13:00    192.168.10.1        443         500
7   01/01/2019 13:00    192.168.10.2        80          100
8   01/01/2019 13:00    192.168.10.3        443         90

我做错了什么?

以下适用于 BigQuery 标准 SQL

#standardSQL
SELECT time, ip_address, 
  ARRAY_AGG(STRUCT(port, mbps) ORDER BY mbps DESC LIMIT 1)[OFFSET(0)].*
FROM `project.dataset.table`
GROUP BY time, ip_address

您可以使用您问题中的示例数据来测试和使用上面的示例,如下例所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT '01/01/2019 12:20' time, '192.168.10.1' ip_address, 443 port, 100 mbps UNION ALL
  SELECT '01/01/2019 12:20', '192.168.10.1', 80, 120 UNION ALL
  SELECT '01/01/2019 12:20', '192.168.10.2', 80, 200 UNION ALL
  SELECT '01/01/2019 12:20', '192.168.10.1', 80, 110 UNION ALL
  SELECT '01/01/2019 12:40', '192.168.10.2', 443, 200 UNION ALL
  SELECT '01/01/2019 12:40', '192.168.10.3', 443, 300 UNION ALL
  SELECT '01/01/2019 12:40', '192.168.10.2', 443, 200 UNION ALL
  SELECT '01/01/2019 12:40', '192.168.10.1', 443, 300 UNION ALL
  SELECT '01/01/2019 13:00', '192.168.10.3', 443, 90 UNION ALL
  SELECT '01/01/2019 13:00', '192.168.10.2', 80, 100 UNION ALL
  SELECT '01/01/2019 13:00', '192.168.10.1', 443, 500 
)
SELECT time, ip_address, 
  ARRAY_AGG(STRUCT(port, mbps) ORDER BY mbps DESC LIMIT 1)[OFFSET(0)].*
FROM `project.dataset.table`
GROUP BY time, ip_address
-- ORDER BY time, ip_address

结果

Row time                ip_address      port    mbps     
1   01/01/2019 12:20    192.168.10.1    80      120  
2   01/01/2019 12:20    192.168.10.2    80      200  
3   01/01/2019 12:40    192.168.10.1    443     300  
4   01/01/2019 12:40    192.168.10.2    443     200  
5   01/01/2019 12:40    192.168.10.3    443     300  
6   01/01/2019 13:00    192.168.10.1    443     500  
7   01/01/2019 13:00    192.168.10.2    80      100  
8   01/01/2019 13:00    192.168.10.3    443     90