我(想)我有一個有趣的窗口場景,與網站股票可用性跟蹤有關,通過標準SQL進行處理。這是試圖建立了基於該推,從股票的「手頭」數量爲某個特定產品BigQuery - 窗口化股票分類
事件我們有與此相關的問題3種事件類型時股票頭寸的看法:
StocklevelUpdated(PUSH):在每天晚上的午夜,我們會針對倉庫中給定產品的onHandQty可用性級別進行新的更新。如果每個產品的onHandQty數量作爲下一個交易日的新值,這基本上是一個很難'重置'。 (注意:即使沒有變化,這實際上每晚都會發送一條記錄)。
OrderAccepted(PULL):那一天的過程中,也有產品,在這種情況下對股票負值許多「OrderAccepted」事件「onHandQtyDelta」(現在還不到賣)。 -2訂購了2件產品。
OrderCancelled:可以有,以及對產品的數量cancelleations,這對「onHandQtyDelta」一個積極的價值,因爲它添加回可用庫存銷售)
下面是一個tabluar按照的時間順序查看一個稍微簡化版本的數據(注意:這顯示單個產品當然有很多)。
onHandQtyDelta - 換到onHandQty作爲本次活動
onHandQty的結果 - 這是在這一點上的淨正及時後增量影響。
現在雖然上圖中顯示的所有值很好ledgering出來(雖然,注意29是這些午夜復位之一),在現實中,並非所有的數據可用,需要導出的一個值這些訂單事件類型中的每一個。即1丟失。
onHandQty:實際數據集中具有絕對值onHandQty的唯一行是「StocklevelUpdated」事件。實際上,這會在午夜(例如29)「重置」產品的這個值。日記需要基本追溯到最近的這些。但是,onHandQtyDelta需要派生。
onHandQtyDelta只有OrderAccepts和OrderCancelled事件具有需要用來計算onHandQty的這個值。
所以圖片講千言萬語,所以數據的真實性與看起來像下面的工作:
如何有效地做到這一點(因爲有上百萬行的10秒)做這個?
我的想法是使用窗口和'lag'函數來回顧以前的記錄onHandQty的值,看看它是什麼,然後做加法或減法來得到新的onHandQty值。
問題是,然後是一個遞歸問題,因爲前一個事件本身需要回顧它以前的等等....直到你到一個stocklevelUpdated事件,因爲這是唯一的事件具有實際值然後從中前進。但是,當你不知道還有多遠才能獲得這樣的事件時,如何使用窗口來做到這一點 - 可以是之間的任何數量的OrderAccepts和Cancells(或沒有!)
也許聰明的數組,產品行放入數組並執行一些數組agg函數?
我認爲Ive得到stuckon思維的窗口是這樣的,也許由一個簡單的解決方案蒙上陰影!對不起,所有的細節,但不想模糊我需要幫助。
列出了啓動測試數據集工作過(我剛剛整理它的產品和時間用於創建圖像的目的)
WITH stock_changes AS (
SELECT
"StocklevelUpdated" AS eventName,
Timestamp("2017-06-29T23:59:59") AS stockLevelEventAt,
"PRODUCT_190035001612" AS productId,
null AS onHandQtyDelta,
23 AS onHandQty
UNION ALL (
SELECT
"StocklevelUpdated" AS eventName,
Timestamp("2017-06-29T23:59:59") AS stockLevelEventAt,
"PRODUCT_4545423454545" AS productId,
null AS onHandQtyDelta,
120 AS onHandQty)
UNION ALL (
SELECT
"OrderAccepted" AS eventName,
Timestamp("2017-06-30T01:02:20") AS stockLevelEventAt,
"PRODUCT_190035001612" AS productId,
-2 AS onHandQtyDelta,
null AS onHandQty)
UNION ALL (
SELECT
"OrderAccepted" AS eventName,
Timestamp("2017-06-30T02:19:20") AS stockLevelEventAt,
"PRODUCT_190035001612" AS productId,
-3 AS onHandQtyDelta,
null AS onHandQty)
UNION ALL (
SELECT
"OrderAccepted" AS eventName,
Timestamp("2017-06-30T05:13:20") AS stockLevelEventAt,
"PRODUCT_4545423454545" AS productId,
-3 AS onHandQtyDelta,
null AS onHandQty)
UNION ALL (
SELECT
"OrderCancelled" AS eventName,
Timestamp("2017-06-30T13:02:20") AS stockLevelEventAt,
"PRODUCT_190035001612" AS productId,
+2 AS onHandQtyDelta,
null AS onHandQty)
UNION ALL (
SELECT
"OrderCancelled" AS eventName,
Timestamp("2017-06-30T11:02:20") AS stockLevelEventAt,
"PRODUCT_4545423454545" AS productId,
2 AS onHandQtyDelta,
null AS onHandQty)
UNION ALL (
SELECT
"StocklevelUpdated" AS eventName,
Timestamp("2017-06-30T23:59:59") AS stockLevelEventAt,
"PRODUCT_190035001612" AS productId,
null AS onHandQtyDelta,
29 AS onHandQty)
UNION ALL (
SELECT
"StocklevelUpdated" AS eventName,
Timestamp("2017-06-30T23:59:59") AS stockLevelEventAt,
"PRODUCT_4545423454545" AS productId,
null AS onHandQtyDelta,
140 AS onHandQty)
)
SELECT *
FROM stock_changes
order by productId, stockLevelEventAt ASC
米哈伊爾·哇感謝, - 病患者需要坐下來消化它現在有點大加讚賞。首先獲得正確的結果顯然是一個很好的開始,然後可以優化大約1200萬行這將是。 –
當然。順便說一句,這個查詢有很好的機會來擴展你的真實數據與數百萬行 - 這取決於你的productID/days/etc。分配。你只是嘗試:o)並且不要忘記接受和投票,如果你會找到合適的 –
很酷知道!只需查看完整數據集的SQL即可。如果有另一列「位置」(2個價值觀,「英國」或「美國」),其中實際上的productId +位置是獨一無二的,而並非只是productId參數(即相同的productId,不同的位置),這將如何變化?我認爲我已經通過將位置添加到分區和順序中來解決問題,但只是想檢查一下?此外,有時我們吹噓,所以onHandQty可以去負(以前是0,那麼我們有一個orderCreated,它爲負則)......目前,它顯示爲「零」。太好了,謝謝! –