【发布时间】:2020-06-02 02:57:35
【问题描述】:
我在 Google Bigquery 中有一个大型数据集,其中包含数百万行我正在尝试清理的脏数据(应用程序跟踪)。我的一个问题是,对于应用程序中触发的不同事件,相同的数据被发送到不同的列。我的意思是,对于某些事件,该国家/地区可能被发送到自定义维度 1,但对于其他事件,该国家/地区被发送到自定义维度 147。我无法发布实际数据,但SELECT * FROM table_with_dirty_data 会产生如下内容:
date | session | eventAction | cd001 | cd002 | cd004 | cd005
-----|---------|-------------|-------|----------|----------|-------
1 | 1 | 'event_1' | '1' | 'Pizza' | null | '21'
1 | 1 | 'event_2' | '10' | '25' | 'Pizza' | '14.56'
1 | 1 | 'event_3' | '3.1' | null | '15' | 'France'
1 | 2 | 'event_1' | '6' | 'Burger' | null | '21'
1 | 2 | 'event_2' | '21' | '25' | 'Burger' | '12.6'
这里的最终目标是最终得到一个可以分析的干净表。像这样的:
date | session | eventAction | country | vendor | product | price
-----|---------|-------------|----------|----------|----------|-------
1 | 1 | 'event_1' | 'France' | '1' | 'Pizza' | '14.56'
1 | 1 | 'event_2' | 'France' | '1' | 'Pizza' | '14.56'
1 | 1 | 'event_3' | 'France' | '1' | 'Pizza' | '14.56'
1 | 2 | 'event_1' | 'Spain' | '25' | 'Burger' | '12.6'
1 | 2 | 'event_2' | 'Spain' | '25' | 'Burger' | '12.6'
我知道某些事件需要某种程度的统计插补和数据类型转换,但现在我只关心将每个变量放入自己的列中。所以我创建了一个辅助表(我们称之为matrix),如下所示:
event_name | variable_1 | variable_2 | variable_3
-----------|------------|------------|----------
'event_1' | 'cd020' | 'cd035' | 'cd120'
'event_2' | 'cd020' | 'cd146' | 'cd056'
'event_3' | 'cd001' | 'cd020' | 'cd035'
以此类推,其中variable_#列的每个单元格中的值就是table_with_dirty_data中可以找到信息的列名。也就是说,variable_1 可以在名为 cd020 的列中找到 event_name 为“event_1”和“even_2”的事件,但在名为 cd001 的列中找到 event_name 为“event_3”的事件。所以基本上matrix 所做的是将每个变量为每个事件发送到哪个自定义维度。
现在...我在 table_with_dirty_data 上有数百个不同的事件,matrix 包含所有 200 个 GA 自定义维度,所以做类似的事情
SELECT
CASE
WHEN event_name = 'event_1' THEN cd020
WHEN event_name = 'event_2' THEN cd020
WHEN event_name = 'event_3' THEN cd001
END AS variable_1
, CASE
WHEN event_name = 'event_1' THEN cd035
WHEN event_name = 'event_2' THEN cd146
WHEN event_name = 'event_3' THEN cd020
END AS variable_2
, CASE
WHEN event_name = 'event_1' THEN cd120
WHEN event_name = 'event_2' THEN cd056
WHEN event_name = 'event_3' THEN cd035
END AS variable_3
FROM table_with_dirty_data
会花很长时间,而且很容易出错。我想要做的是使用SELECT 语句从存储信息的table_with_dirty_data 返回列名(cd###),并使用WHILE 循环所有不同的事件。因此,例如,event_name = 'event_1' 会是这样的:
SELECT
CASE WHEN event_name = 'event_1' THEN (SELECT variable_1 FROM matrix WHERE event_name = 'event_1') END AS variable_1
, CASE WHEN event_name = 'event_1' THEN (SELECT variable_2 FROM matrix WHERE event_name = 'event_1') END AS variable_2
, CASE WHEN event_name = 'event_1' THEN (SELECT variable_3 FROM matrix WHERE event_name = 'event_1') END AS variable_3
FROM table_with_dirty_data
WHERE event_name = 'event_1'
这里的目标是,然后我可以循环使用所有 event_names 的数组(这很容易实现)。最终我需要一张桌子上的所有事件,但我可以有一张桌子来策划每个事件,只要它可以以编程方式完成(我个人不知道它在 GBQ 中是否可能......会有检查)。
问题是我使用的SELECT 语句被评估为字符串,因此CASE 子句中的查询结果是字符串文字。例如,如果我要为 event = 'event_1' 运行它,
SELECT variable_1 FROM matrix WHERE event_name = 'event_1'
评估为
'cd020'
然后导致外部查询变为
SELECT
CASE WHEN event_name = 'event_1' THEN 'cd020' END AS variable_1
, CASE WHEN event_name = 'event_1' THEN 'cd035' END AS variable_2
, CASE WHEN event_name = 'event_1' THEN 'cd120' END AS variable_3
FROM table_with_dirty_data
WHERE event_name = 'event_1'
生成这样的表格
event_name | variable_1 | variable_2 | variable_3
-----------|------------|------------|----------
'event_1' | 'cd020' | 'cd035' | 'cd120'
'event_1' | 'cd020' | 'cd035' | 'cd120'
'event_1' | 'cd020' | 'cd035' | 'cd120'
而不是每次找到事件“event_1”时返回存储在cd020、cd035 或cd120 列中的值。
有谁知道取消引用这些内部查询结果的方法,以便在执行外部查询时将它们转换为列名(因此“cd020”变为cd020)??
PS:如果有人知道的话,我也对完全不同的策略持开放态度。
【问题讨论】:
-
我可以向您推荐更好的方法,但是您能否提供几行示例数据和预期输出?您想为每个事件分别创建一个表格吗?
-
@SabriKaragönen 我已经编辑了这个问题。希望现在更清楚了。真的很期待听到不同的方式。谢谢
标签: google-bigquery