BigQuery:如何在重复记录中插入新值?
Posted
技术标签:
【中文标题】BigQuery:如何在重复记录中插入新值?【英文标题】:BigQuery: How to insert a new value in repeated record? 【发布时间】:2018-11-05 11:00:53 【问题描述】:我想保存用户状态的历史记录。
为此,我有一个包含两个列的表:user_identifier 和 status。
user_identifier 是一个字符串,status 是一个重复的记录,键:值对:日期和状态。
当用户更改状态(例如从活动状态变为非活动状态)时,我想更新此表并添加新状态,同时保留旧状态。
这是表架构:
[
"description": "user identifier",
"mode": "REQUIRED",
"name": "user_id",
"type": "STRING"
,
"description": "status - can be either sent or pending, initial state is pending",
"mode": "REPEATED",
"name": "status",
"type": "RECORD",
"fields": [
"name": "status_date",
"type": "DATE",
"mode": "REQUIRED"
,
"name": "value",
"type": "STRING",
"mode": "REQUIRED"
]
]
这甚至可以在此架构中插入新的用户状态吗?我应该重新设计架构吗? 如何在 BigQuery 中正确执行此操作,以利用其嵌套功能?
【问题讨论】:
【参考方案1】:以下是 BigQuery 标准 SQL,并假设您有一个状态表 project.dataset.statuses
,如您在问题中所述,并且您有更新表 project.dataset.updates
,您可以在其中累积更新以定期更新状态表
所以虚拟数据可能看起来像
WITH `project.dataset.statuses` AS (
SELECT 'a' user_id, [STRUCT<status_date DATE, value STRING>('2018-11-03', 'pending')] status UNION ALL
SELECT 'b', [STRUCT<status_date DATE, value STRING>('2018-11-04', 'pending')] UNION ALL
SELECT 'c', []
), `project.dataset.updates` AS (
SELECT 'a' user_id, [STRUCT<status_date DATE, value STRING>('2018-11-05', 'sent')] new_statuses UNION ALL
SELECT 'c', [STRUCT<status_date DATE, value STRING>('2018-11-05', 'pending')]
)
其中更新表具有完全相同的架构并表示需要添加到主表的新更新
SELECT 下方返回加入状态
#standardSQL
SELECT
t.user_id,
IF(u.user_id IS NULL, status, ARRAY_CONCAT(status, new_statuses)) status
FROM `project.dataset.statuses` t
LEFT JOIN `project.dataset.updates` u
ON t.user_id = u.user_id
您可以使用下面的 DDL 来“更新”它们的状态表
#standardSQL
CREATE OR REPLACE TABLE `project.dataset.statuses` AS
SELECT
t.user_id,
IF(u.user_id IS NULL, status, ARRAY_CONCAT(status, new_statuses)) status
FROM `project.dataset.statuses` t
LEFT JOIN `project.dataset.updates` u
ON t.user_id = u.user_id
如果应用于虚拟数据
状态:
Row user_id status.status_date status.value
1 a 2018-11-03 pending
2 b 2018-11-04 pending
3 c
更新:
Row user_id new_statuses.status_date new_statuses.value
1 a 2018-11-05 sent
3 c 2018-11-05 pending
结果将是
Row user_id status.status_date status.value
1 a 2018-11-03 pending
2018-11-05 sent
2 b 2018-11-04 pending
3 c 2018-11-05 pending
如果updates
表可以包含尚未在主表中的新用户 - 下面将处理这种情况
#standardSQL
-- CREATE OR REPLACE TABLE `project.dataset.statuses` AS
SELECT
IFNULL(t.user_id, u.user_id) user_id,
CASE
WHEN t.user_id = u.user_id THEN ARRAY_CONCAT(status, new_statuses)
WHEN t.user_id IS NULL THEN new_statuses
WHEN u.user_id IS NULL THEN status
END status
FROM `project.dataset.statuses` t
FULL JOIN `project.dataset.updates` u
ON t.user_id = u.user_id
【讨论】:
以上是关于BigQuery:如何在重复记录中插入新值?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 bigrquery 库将非重复记录插入 BigQuery?