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

时间:2019-02-04 15:09:12

标签: google-bigquery standard-sql

对于每20分钟的时间间隔,我尝试查找带宽的最大值(下表中的列mbps),每个唯一的IP地址都会生成并带有相应的端口号。

每个IP地址每20分钟显示一次或不多次显示。每次以20分钟的时间间隔记录一次IP地址时,它可能会列出相同的端口号,也可能没有。

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

目标是在二十分钟的每个时间段内,仅选择和列出每个唯一的IP地址一次,并按DES顺序按mbps排序。

根据数据注入时间对表进行分区。

我计划编写一个cron作业,以自动执行此查询。 Cron作业每周7天每小时运行一次。该查询将使用标准SQL。

原始表:

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

我得到这张桌子

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

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

以下是用于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