目前,我正努力在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,但看起来很多)。
是否有进行这种查询的适当方法或其他方法来优化仅检索已过滤列的方法?
答案 0 :(得分:2)
是否有进行这种查询的适当方法(通过正则表达式过滤器过滤Google BigQuery列)...
无法通过纯BigQuery SQL进行此类查询-如果需要,可以https://intellipaat.com/community/5478/getting-console-log-output-from-chrome-with-selenium-python-api-bindings。
同时,您可以使用选择的任何submit feature request来以编程方式构建所需的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
根据我的经验-在涉及列动态列表的大多数实际用例中,与在列中显示相比,上述输出要有用得多
很显然,如果您使用更复杂的过滤器,则可以用REGEXP_CONTAINS替换STARTS_WITH(..., '"TP_001')