我一直在使用LAG()
返回ARRAY of STRUCT
中上一行的值,并且{{1}似乎不支持LAG/LEAD
之类的导航窗口功能}}。
这听起来不太理想,但是您需要UNNEST
全部和(重新)UNNEST
!!
例如说您要上一行的金额:
编辑:架构详细信息:
发票架构:
PARTITION BY
预期输出:
docID STRING, lines STRUCT<lineID STRING, amount NUMERIC>
docID STRING, lines STRUCT<lineID STRING, amount NUMERIC, prev_amount NUMERIC>
这非常慢。我希望我们可以通过某种方式将ARRAY作为窗口框架使用。
是否有其他选择??我正在使用SELECT
docID, lineID, amount
,LAG(amount) OVER (PARTITION BY docID ORDER by lineID) prev_amount
FROM invoices, UNNEST(lines)
,但这可能适用于其他DBMS。
更新:我使用
BigQuery
提出了以下替代方案。更快,也许这就是OFFSET的用途,这很丑陋,在我看来可能更简单。
WITH OFFSET
答案 0 :(得分:1)
以下显示了更好的性能(至少是我为了快速测试而使用的少量)。执行计划看起来也更好(至少对我而言)
#standardSQL
SELECT
lines[OFFSET(pos)].*, lines[SAFE_OFFSET(pos - 1)].amount prev_amount
FROM invoices, UNNEST(GENERATE_ARRAY(0, ARRAY_LENGTH(lines) - 1)) pos
注意:我假设遵循模式[STRUCT<docID INT64, lineID INT64, amount FLOAT64>] lines
更新:调整为与您刚提供的真实架构相匹配
#standardSQL
SELECT docID, ARRAY(
SELECT AS STRUCT
lines[OFFSET(pos)].*,
lines[SAFE_OFFSET(pos - 1)].amount prev_amount
FROM UNNEST(GENERATE_ARRAY(0, ARRAY_LENGTH(lines) - 1)) pos
) lines
FROM invoices
答案 1 :(得分:1)
在米哈伊尔的答案的下面,改用WITH OFFSET
表现更好(55s比170s,超过5000万行)
#standardSQL
SELECT docID, ARRAY(
SELECT AS STRUCT
l.*,
lines[SAFE_OFFSET(pos - 1)].amount prev_amount
FROM UNNEST(lines) l WITH OFFSET pos
) lines
FROM invoices
注意:如果将ORDER BY
或WHERE
子句添加到更改原始索引的取消嵌套中,则此方法将无法按原样工作。
这是我的用例,如果您是在相对位置在过滤后的数组中定位,则应该先使用子查询来创建过滤后的数组,然后再使用组合UNNEST WITH OFFSET
+ OFFSET/ORDINAL
在外部查询中。