目前,我正努力在Google Big Query中创建快速且优化的查询。
假设有表,有1万行和4k列:
| TP_001_A | TP_001_B | TP_002_A | TP_002 | ... | TP_099_B |
----+----------+----------+----------+----------+----------+----------+
1 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.37 |
2 | 0.33 | 0.33 | 0.31 | 0.33 | 0.33 | 0.33 |
3 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 |
4 | 0.35 | 0.33 | 0.33 | 0.33 | 0.34 | 0.33 |
...
9999| 0.33 | 0.33 | 0.33 | 0.33 | 0.33 | 0.33 |
我的任务是基于正则表达式过滤器选择列(例如,仅名称从TP_001开头的列),结果如下表:
| TP_001_A | TP_001_B |
----+----------+----------+
1 | 0.33 | 0.33 |
2 | 0.33 | 0.33 |
3 | 0.33 | 0.33 |
4 | 0.35 | 0.33 |
...
9999| 0.33 | 0.33 |
到现在为止,我已经解决了这个问题并查询了整个表,然后使用pandas库对其进行了过滤,这很慢,这是因为下载时间较长,并且大表中的pandas总体缓慢。
搜索网络后,我发现可以通过查询检索列名,例如:
SELECT column_name
FROM my_view.INFORMATION_SCHEMA.COLUMNS
WHERE table_name="my_table"
我可以在其中使用REGEXP_EXTRACT_ALL函数并过滤适当的列名的方法,但这给了我单独的表,该表很难在主查询中使用。
但是此解决方案有一个问题:尽管处理速度非常快,但是正在处理大量数据(指示显示为10MB,但看起来很多)。
是否有进行这种查询的适当方法或其他方法来优化仅检索已过滤的列的方法?
有没有做这种查询的适当方法(通过正则表达式过滤器过滤Google BigQuery列)...
无法使用纯BigQuery SQL进行此类查询-如果您愿意,可以提交功能请求。
同时,您可以使用自己选择的任何BigQuery客户端库以编程方式构建所需的select语句并执行-超级简单且可行的选项
...或其他优化检索仅过滤列的方法?
如果由于某种原因您不得不使用纯BQ SQL-我看到的唯一选择是按以下示例进行展平(对您的问题中的伪数据进行了稍微修改)
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, 0.3301 TP_001_A, 0.3305 TP_001_B, 0.3309 TP_002_A, 0.3313 TP_002, 0.3317 TP_003, 0.3721 TP_099_B UNION ALL
SELECT 2, 0.3302, 0.3306, 0.3110, 0.3314, 0.3318, 0.3322 UNION ALL
SELECT 3, 0.3303, 0.3307, 0.3311, 0.3315, 0.3319, 0.3323 UNION ALL
SELECT 4, 0.3504, 0.3308, 0.3312, 0.3316, 0.3420, 0.3324
)
SELECT id, TRIM(kv.key, '"') col, kv.value
FROM `project.dataset.table` t,
UNNEST(ARRAY(
SELECT AS STRUCT SPLIT(kv, ':')[OFFSET(0)] key, SPLIT(kv, ':')[OFFSET(1)] value
FROM UNNEST(SPLIT(TRIM(TO_JSON_STRING(t), '{}'))) kv
WHERE STARTS_WITH(SPLIT(kv, ':')[OFFSET(0)], '"TP_001')
)) kv
-- ORDER BY id
结果
Row id col value
1 1 TP_001_A 0.3301
2 1 TP_001_B 0.3305
3 2 TP_001_A 0.3302
4 2 TP_001_B 0.3306
5 3 TP_001_A 0.3303
6 3 TP_001_B 0.3307
7 4 TP_001_A 0.3504
8 4 TP_001_B 0.3308
根据我的经验-在涉及列动态列表的大多数实际用例中,上述输出比在列中显示的实用得多
显然,STARTS_WITH(..., '"TP_001')
如果您有更复杂的过滤器,则可以用REGEXP_CONTAINS替换
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句