我想在count
级别总结id
。对于每个id
摘要行,我还希望有一个STRUCTs的ARRAY字段,它为a1
和a2
这两个属性的每一个汇总数据。
这是我设法做到的方式,它具有4个查询和6条SELECT
语句,但是我认为必须有一种更简化的方法来实现此目的。
1)对于每个属性摘要,在执行ARRAY_AGG()
之后在外部查询中执行SUM()
似乎可以一步完成,尽管不能将{{1} }和SUM()
之内。
2)首先对ARRAY_AGG()
进行每个摘要,然后对每个属性进行摘要,然后将所有这些摘要进行合并,似乎应该在一个步骤中完成。
请注意,我确实重视此查询的可读性。但我认为这里肯定缺少一些可读的“速记”。
id
答案 0 :(得分:2)
但是我认为这里必须缺少一些可读的“速记”。
下面产生的结果与原始查询完全相同,但仍很可读,简单(我认为很性感)
#standardSQL
CREATE TEMP FUNCTION x(a ANY TYPE) AS (
ARRAY(SELECT AS STRUCT val, SUM(`count`) `count` FROM UNNEST(a) GROUP BY val)
);
SELECT id, SUM(`count`) AS total,
x(ARRAY_AGG(STRUCT(a1 AS val, `count`))) a1,
x(ARRAY_AGG(STRUCT(a2 AS val, `count`))) a2
FROM data
GROUP BY id
您可以使用虚拟数据(如下面的示例n)进行测试,操作
#standardSQL
CREATE TEMP FUNCTION x(a ANY TYPE) AS (
ARRAY(SELECT AS STRUCT val, SUM(`count`) `count` FROM UNNEST(a) GROUP BY val)
);
WITH data AS (
SELECT "A" AS id, 1 AS `count`, "a" AS a1, "d" AS a2 UNION ALL
SELECT "A", 2, "a", "e" UNION ALL
SELECT "A", 3, "b", "d" UNION ALL
SELECT "A", 4, "a", "d" UNION ALL
SELECT "B", 2, "a", "e" UNION ALL
SELECT "B", 3, "b", "e" UNION ALL
SELECT "B", 4, "a", "d"
)
SELECT id, SUM(`count`) AS total,
x(ARRAY_AGG(STRUCT(a1 AS val, `count`))) a1,
x(ARRAY_AGG(STRUCT(a2 AS val, `count`))) a2
FROM data
GROUP BY id
有结果
答案 1 :(得分:0)
这有点奇怪,因为您有意为a1和a2分组创建独立的重复。这意味着对a1的任何分析都不关心a2,反之亦然,因为一旦丢失了两个值之间的关系信息,就无法将它们重新组合。
如果确实需要使用a1和a2值的组合进行关联,请考虑将这些组合在一起放在结构中,而不是构建两个独立的数组。您还可以同时计算每个ID的总数:
SELECT
id,
SUM(subtotal) as total,
ARRAY_AGG(STRUCT(a1, a2, subtotal)) as partial_sums
FROM
(
SELECT
id,
a1,
a2,
SUM(count) as subtotal
FROM data
GROUP BY id, a1, a2
)
GROUP BY id
假设您将部分汇总保留为表格,则可以稍后扩展部分摘要以计算仅a1或仅a2的细分。下面的示例使用ANY_VALUE来投影总数,因为所有行共享相同的值,并且避免了额外的GROUP BY。但是,对于用例而言,使用外部查询来构建数组可能是完全不必要的。
SELECT
id,
ANY_VALUE(total) as total,
ARRAY_AGG(a1_summary) as a1_partial_sums
FROM
(
SELECT
id,
total,
STRUCT(p.a1, SUM(p.subtotal)) as a1_summary
FROM
`partial_summary_table`
CROSS JOIN UNNEST(partial_sums) as p
GROUP BY id, total, p.a1
)
GROUP BY id