【发布时间】:2018-06-16 02:14:04
【问题描述】:
我们正在开发一个应用程序,它将请求存储在一个表中,并将响应存储在另一个表中(当然)。每个请求可以有多个响应,并且我们将请求 ID 存储在两个表中。
最初,我认为我们可以使用请求中的左连接 -> 响应来计算每个匹配条件的总数:
SELECT source, COUNT(*) as requests, COUNT(responses.request_id) as responses
FROM DATASET.requests
LEFT JOIN DATASET.responses ON requests.id = responses.request_id
WHERE source = "source1"
GROUP BY source
有 70 个请求符合 WHERE 条件,30 个响应符合这个条件。预期输出为:“source1, 70, 30”。 从那以后,我了解了更多关于 JOIN 行为的信息,而我们得到了“source1, 259, 207”。两边有重复的ID。
我能够得到我想要的结果的唯一方法是创建一个巨大的查询,以及多个在给定条件过滤的 ID 集中匹配的完整子查询。然后使用过滤后的 ID 集来真正提取我们的字段、统计信息等。
SELECT * FROM
(SELECT COUNT(*) as responses FROM DATASET.responses
WHERE id IN (SELECT id FROM DATASET.requests WHERE source =
"source1"))
,
(SELECT source, COUNT(*) as requests
FROM PUBDATA.requests
WHERE id IN (SELECT id FROM DATASET.requests WHERE source = "source1")
GROUP BY source)
这看起来很糟糕。我曾尝试使用 CTE 来收集我们想要的 ID 列表,并使用 WHERE id/request_id IN (cte.id) 但这显然是不可能的,除非我们在 cte 上加入,这再次产生错误和成倍的结果。
由于我们想在查询中添加额外的统计信息,这将需要更多的 WHERE 子句,我担心这个怪物会继续增长并且难以实现。
如果有更好的方法,请告诉我。谢谢!
编辑 - 请求的示例架构 请求
id (String), source (String), partner_ids (Integer array), user_agent (String), timestamp (Timestamp), ...
回复
request_id (String, from requests.id), partner_id (Integer), is_billed (boolean), price_charged (float, null if is_billed = false), response_categories (String array, not from requests), ...
挑战在于我们必须主要查询 Requests 表以获取与我们的条件匹配的 ID 值列表,然后查询每个表的统计信息(例如 counts、count where is_billed 等)以获取一份合并报告。我们可能还需要从每个表的条件中提取 ID 池(例如 where requests.source = 'source1' 和response.response_categories IN 'action')
【问题讨论】:
-
样本数据和期望的结果会有所帮助。
标签: sql google-bigquery