我有一个表,其中有许多行是原子动作的记录。我希望将这些原子动作的集合归为元动作,其中,定义元动作的定义是时间戳在另一行的90天之内,且三个特定字段的值相同(从,到和主题) )。
我希望将1-n行分组为单个元操作。
这甚至可能吗?
row | timestamp | from | to | subject | some_data
----------------------------------------------------
1 | 1/1/2018 | A | B | RED | asdfasdf
2 | 1/2/2018 | A | B | RED | asdfasdf
3 | 1/3/2018 | A | B | RED | asdfasdf
4 | 1/5/2018 | C | D | BLUE | asdfasdf
5 | 1/6/2018 | E | F | GREEN | asdfasdf
6 | 1/8/2018 | G | H | YELLOW | asdfasdf
7 | 1/9/2018 | G | H | YELLOW | asdfasdf
8 | 1/6/2019 | G | H | YELLOW | asdfasdf
因此,第1,2,3行将作为一条记录输出,第4行将作为一条记录输出,第5行将成为一条记录,第6,7行作为一项记录,第8行作为一条记录(注意6,7是2018年,而8是2019)。
编辑:我希望输出列与输入列相同,但是timestamp的值将是任何给定分组中最早的timestamps。
答案 0 :(得分:1)
我不确定结果集是什么,但这是对您的请求的字面解释:
select array_agg(t)
from t
group by from, to, subject, extract(year from timestamp);
这将生成一个值的结构数组。
如果只需要数组中的ID:
select from, to, subject, extract(year from timestamp) as year,
array_agg(id)
from t
group by from, to, subject, extract(year from timestamp);
注意:诸如from
和to
之类的关键字对于列而言是非常糟糕的名称。我认为这仅用于说明。如果没有,则需要用引号将其包围。
答案 1 :(得分:0)
以下是用于BigQuery标准SQL
#standardSQL
SELECT ARRAY_AGG(ts ORDER BY day LIMIT 1)[OFFSET(0)] ts, `from`, `to`, `subject`, STRING_AGG(some_data, '; ') all_some_data
FROM (
SELECT *, COUNTIF(flag OR (flag IS NULL)) OVER(PARTITION BY `from`,`to`,`subject` ORDER BY UNIX_DATE(day)) grp
FROM (
SELECT *, PARSE_DATE('%d/%m/%Y', ts) day,
UNIX_DATE(PARSE_DATE('%d/%m/%Y', ts)) -
LAG(UNIX_DATE(PARSE_DATE('%d/%m/%Y', ts)))
OVER(PARTITION BY `from`,`to`,`subject` ORDER BY UNIX_DATE(PARSE_DATE('%d/%m/%Y', ts))) > 90 AS flag
FROM `project.dataset.table`
)
)
GROUP BY `from`, `to`, `subject`, grp
如果要应用于您的问题的样本数据-结果为
Row ts from to subject all_some_data
1 1/1/2018 A B RED asdfasdf1; asdfasdf2; asdfasdf3
2 1/5/2018 C D BLUE asdfasdf4
3 1/6/2018 E F GREEN asdfasdf5
4 1/8/2018 G H YELLOW asdfasdf6; asdfasdf7
5 1/6/2019 G H YELLOW asdfasdf8