SQL: 获取天数时间序列的结果
SQL: Get results of time series of days backwards
给出的是每天保存的实体的 table 股票价值。我想得到:
给出今天缺货(数量 = 0)且前一天没有缺货的所有实体。
这是前天和前天的对比。等等。
我的方法可行,但我必须手动创建 WHERE 条件中的部分。
查询 2019 年全年怎么样?
#standardSQL
WITH
TableStockDaily AS (
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty
)
SELECT
sd1.ExportDate AS DateOutOfStock,
sd2.ExportDate AS DateNotOutOfStock,
sd1.EntityId AS EntityId,
sd1.Qty AS Qty1,
sd2.Qty AS Qty2
FROM
TableStockDaily sd1
LEFT JOIN
TableStockDaily sd2
ON
sd1.EntityId = sd2.EntityId
WHERE
sd1.Qty = 0
AND sd2.Qty > 0
AND sd1.ExportDate > sd2.ExportDate
AND
(
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -1 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -7 DAY)
)
)
我认为您正在寻找 LAG()
。此 window 函数可用于根据排序标准(此处 ExportDate
)恢复一组记录(此处为共享相同 EntityID
的记录)中给定列的值:
SELECT *
FROM (
SELECT
EntityId,
ExportDate AS DateOutOfStock,
Qty AS QtyOutOfStock,
LAG(ExportDate) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS DateNotOutOfStock,
LAG(Qty) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS QtyNotOutOfStock
FROM
TableStockDaily sd1
) x
WHERE QtyOutOfStock = 0 AND QtyNotOutOfStock > 0
给出的是每天保存的实体的 table 股票价值。我想得到:
给出今天缺货(数量 = 0)且前一天没有缺货的所有实体。
这是前天和前天的对比。等等。
我的方法可行,但我必须手动创建 WHERE 条件中的部分。
查询 2019 年全年怎么样?
#standardSQL
WITH
TableStockDaily AS (
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-10 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-11 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-12 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-13 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-14 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-15 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 0 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1001 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1002 AS EntityId, 1 as Qty UNION ALL
SELECT TIMESTAMP('2019-10-16 00:00:00 UTC') AS ExportDate, 1003 AS EntityId, 1 as Qty
)
SELECT
sd1.ExportDate AS DateOutOfStock,
sd2.ExportDate AS DateNotOutOfStock,
sd1.EntityId AS EntityId,
sd1.Qty AS Qty1,
sd2.Qty AS Qty2
FROM
TableStockDaily sd1
LEFT JOIN
TableStockDaily sd2
ON
sd1.EntityId = sd2.EntityId
WHERE
sd1.Qty = 0
AND sd2.Qty > 0
AND sd1.ExportDate > sd2.ExportDate
AND
(
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -1 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -2 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -3 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -4 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
)
OR
(
DATE(sd1.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -5 DAY)
AND DATE(sd1.ExportDate) >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) <= DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -6 DAY)
AND DATE(sd2.ExportDate) > DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL -7 DAY)
)
)
我认为您正在寻找 LAG()
。此 window 函数可用于根据排序标准(此处 ExportDate
)恢复一组记录(此处为共享相同 EntityID
的记录)中给定列的值:
SELECT *
FROM (
SELECT
EntityId,
ExportDate AS DateOutOfStock,
Qty AS QtyOutOfStock,
LAG(ExportDate) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS DateNotOutOfStock,
LAG(Qty) OVER(PARTITION BY EntityId ORDER BY ExportDate) AS QtyNotOutOfStock
FROM
TableStockDaily sd1
) x
WHERE QtyOutOfStock = 0 AND QtyNotOutOfStock > 0