英文:
How to generate rows for gaps in data with various gap scenarios
问题
我一直无法找到一个适用的可用解决方案。我们的库存表在特定位置的产品库存为零时没有记录。该表每天都会更新前一天的新记录。
我正在尝试创建一个查询,该查询会输出我的库存表中的数据,并为缺失的日期创建一个库存数量为零的记录,按产品 ID 和库存位置 ID 分组,而不是根本没有记录。
以下是库存表中的一些示例数据:
情景1 - 特定库存位置的日期间隔。
原始表格数据:
日期 | 产品 ID | 库存位置 ID | 库存 |
---|---|---|---|
2023-07-12 | 05427 | 31 | 115 |
2023-07-11 | 05427 | 31 | 120 |
2023-07-10 | 05427 | 31 | 120 |
2023-06-27 | 05427 | 31 | 5 |
2023-06-26 | 05427 | 31 | 6 |
*继续的天数... |
情景1 - 期望的查询结果
日期 | 产品 ID | 库存位置 ID | 库存 |
---|---|---|---|
2023-07-12 | 05427 | 31 | 115 |
2023-07-11 | 05427 | 31 | 120 |
2023-07-10 | 05427 | 31 | 120 |
2023-07-09 | 05427 | 31 | 0 |
2023-07-08 | 05427 | 31 | 0 |
2023-07-07 | 05427 | 31 | 0 |
2023-07-06 | 05427 | 31 | 0 |
2023-07-05 | 05427 | 31 | 0 |
2023-07-04 | 05427 | 31 | 0 |
2023-07-03 | 05427 | 31 | 0 |
2023-07-02 | 05427 | 31 | 0 |
2023-07-01 | 05427 | 31 | 0 |
2023-06-30 | 05427 | 31 | 0 |
2023-06-29 | 05427 | 31 | 0 |
2023-06-28 | 05427 | 31 | 0 |
2023-06-27 | 05427 | 31 | 5 |
2023-06-26 | 05427 | 31 | 6 |
*继续的天数... |
情景2 - 特定库存位置的开放日期间隔。
原始表格数据:
日期 | 产品 ID | 库存位置 ID | 库存 |
---|---|---|---|
2023-07-03 | 06357 | 15 | 3 |
2023-07-02 | 06357 | 15 | 3 |
2023-07-01 | 06357 | 15 | 3 |
2023-06-30 | 06357 | 15 | 3 |
2023-06-29 | 06357 | 15 | 3 |
*继续的天数... |
情景2 - 期望的查询结果
日期 | 产品 ID | 库存位置 ID | 库存 |
---|---|---|---|
2023-07-12 | 06357 | 15 | 0 |
2023-07-11 | 06357 | 15 | 0 |
2023-07-10 | 06357 | 15 | 0 |
2023-07-09 | 06357 | 15 | 0 |
2023-07-08 | 06357 | 15 | 0 |
2023-07-07 | 06357 | 15 | 0 |
2023-07-06 | 06357 | 15 | 0 |
2023-07-05 | 06357 | 15 | 0 |
2023-07-04 | 06357 | 15 | 0 |
2023-07-03 | 06357 | 15 | 3 |
2023-07-02 | 06357 | 15 | 3 |
2023-07-01 | 06357 | 15 | 3 |
2023-06-30 | 06357 | 15 | 3 |
2023-06-29 | 06357 | 15 | 3 |
*继续的天数... |
我尝试了以下查询:
SELECT
dates.day,
t1.product_id,
t1.inventory_location_id,
COALESCE(t1.inventory,0) AS qty
FROM (
SELECT
*
FROM
UNNEST(GENERATE_DATE_ARRAY('2020-01-01', CURRENT_DATE(),INTERVAL 1 DAY)) AS day ) dates
LEFT JOIN
inventory_table t1
ON
dates.day = t1.date
和
with dates as (
select day
from unnest(generate_date_array('2020-01-01', current_date(),INTERVAL 1 DAY)) as day
),
temp as (
select *, lead(date) over (partition by product_id, inventory_location_id order by date) as next_day
from inventory_table
order by product_id, inventory_location_id, date
)
Select day, product_id, inventory_location_id
from dates
join temp on dates.day = temp.next_day
但都没有得到来自库存表的空值,更不用说能够创建一个显示缺失日期库存数量为0的记录了。
我还尝试了类似的跨连接查询,但该查询超时。
真的很感激您对这个问题的帮助!提前谢谢!
英文:
I've been unable to find an applicable available solution. Our inventory table does not have records if a product has zero inventory in a specific location. The table updates daily with a new record for the previous day.
I'm trying to create a query that outputs the data in my inventory table but also creates a record for the missing dates with an inventory quantity of zero grouped by product_id and inventory_location_id vs. no record at all.
Here's some example data from the inventory table:
Scenario 1 - Gaps in dates in specific inventory_location_id.
raw table data:
date | product_id | inventory_location_id | inventory |
---|---|---|---|
2023-07-12 | 05427 | 31 | 115 |
2023-07-11 | 05427 | 31 | 120 |
2023-07-10 | 05427 | 31 | 120 |
2023-06-27 | 05427 | 31 | 5 |
2023-06-26 | 05427 | 31 | 6 |
*days continue... |
Scenario 1 - DESIRED QUERY OUTPUT
date | product_id | inventory_location_id | inventory |
---|---|---|---|
2023-07-12 | 05427 | 31 | 115 |
2023-07-11 | 05427 | 31 | 120 |
2023-07-10 | 05427 | 31 | 120 |
2023-07-09 | 05427 | 31 | 0 |
2023-07-08 | 05427 | 31 | 0 |
2023-07-07 | 05427 | 31 | 0 |
2023-07-06 | 05427 | 31 | 0 |
2023-07-05 | 05427 | 31 | 0 |
2023-07-04 | 05427 | 31 | 0 |
2023-07-03 | 05427 | 31 | 0 |
2023-07-02 | 05427 | 31 | 0 |
2023-07-01 | 05427 | 31 | 0 |
2023-06-30 | 05427 | 31 | 0 |
2023-06-29 | 05427 | 31 | 0 |
2023-06-28 | 05427 | 31 | 0 |
2023-06-27 | 05427 | 31 | 5 |
2023-06-26 | 05427 | 31 | 6 |
*days continue... |
Scenario 2 - Open gap in dates in specific inventory_location_id.
raw table data
date | product_id | inventory_location_id | inventory |
---|---|---|---|
2023-07-03 | 06357 | 15 | 3 |
2023-07-02 | 06357 | 15 | 3 |
2023-07-01 | 06357 | 15 | 3 |
2023-06-30 | 06357 | 15 | 3 |
2023-06-29 | 06357 | 15 | 3 |
*days continue... |
Scenario 2 - DESIRED QUERY OUTPUT
date | product_id | inventory_location_id | inventory |
---|---|---|---|
2023-07-12 | 06357 | 15 | 0 |
2023-07-11 | 06357 | 15 | 0 |
2023-07-10 | 06357 | 15 | 0 |
2023-07-09 | 06357 | 15 | 0 |
2023-07-08 | 06357 | 15 | 0 |
2023-07-07 | 06357 | 15 | 0 |
2023-07-06 | 06357 | 15 | 0 |
2023-07-05 | 06357 | 15 | 0 |
2023-07-04 | 06357 | 15 | 0 |
2023-07-03 | 06357 | 15 | 3 |
2023-07-02 | 06357 | 15 | 3 |
2023-07-01 | 06357 | 15 | 3 |
2023-06-30 | 06357 | 15 | 3 |
2023-06-29 | 06357 | 15 | 3 |
*days continue... |
I've tried the following queries:
SELECT
dates.day,
t1.product_id,
t1.inventory_location_id,
COALESCE(t1.inventory,0) AS qty
FROM (
SELECT
*
FROM
UNNEST(GENERATE_DATE_ARRAY('2020-01-01', CURRENT_DATE(),INTERVAL 1 DAY)) AS day ) dates
LEFT JOIN
inventory_table t1
ON
dates.day = t1.date
and
with dates as (
select day
from unnest(generate_date_array('2020-01-01', current_date(),INTERVAL 1 DAY)) as day
),
temp as (
select *, lead(date) over (partition by product_id, inventory_location_id order by date) as next_day
from inventory_table
order by product_id, inventory_location_id, date
)
Select day, product_id, inventory_location_id
from dates
join temp on dates.day = temp.next_day
neither have resulted in getting null values from the inventory table, let alone being able to create a record showing 0 as the inventory quantity for the missing dates.
I also attempted a similar query using a cross join, but that query timed-out.
Really would appreciate help on this one! Thank you in advance!
答案1
得分: 0
以下是翻译好的部分:
使用以下方法(BigQuery标准SQL)
WITH dates AS (
SELECT DATE, product_id, inventory_location_id
FROM (
SELECT product_id, inventory_location_id, GENERATE_DATE_ARRAY(MIN(DATE), CURRENT_DATE()) dates
FROM your_table
GROUP BY product_id, inventory_location_id
), UNNEST(dates) DATE
)
SELECT * REPLACE(IFNULL(inventory, 0) AS inventory)
FROM dates
LEFT JOIN your_table
USING(DATE, product_id, inventory_location_id)
ORDER BY DATE DESC
如果应用于您问题中的示例数据
WITH your_table AS (
SELECT DATE '2023-07-12' DATE, '05427' product_id, 31 inventory_location_id, 115 inventory UNION ALL
SELECT DATE '2023-07-11', '05427', 31, 120 UNION ALL
SELECT DATE '2023-07-10', '05427', 31, 120 UNION ALL
SELECT DATE '2023-06-27', '05427', 31, 5 UNION ALL
SELECT DATE '2023-06-26', '05427', 31, 6
)
输出为
请注意,图片无法在文本中显示。如需查看输出结果的图像,请参考提供的图像链接。
英文:
Use below approach (BigQuery Standard SQL)
WITH dates AS (
SELECT DATE, product_id, inventory_location_id
FROM (
SELECT product_id, inventory_location_id, GENERATE_DATE_ARRAY(MIN(DATE), CURRENT_DATE()) dates
FROM your_table
GROUP BY product_id, inventory_location_id
), UNNEST(dates) DATE
)
SELECT * REPLACE(IFNULL(inventory, 0) AS inventory)
FROM dates
LEFT JOIN your_table
USING(DATE, product_id, inventory_location_id)
ORDER BY DATE DESC
if applied to sample data in your question
WITH your_table AS (
SELECT DATE '2023-07-12' DATE, '05427' product_id, 31 inventory_location_id, 115 inventory UNION ALL
SELECT '2023-07-11', '05427', 31, 120 UNION ALL
SELECT '2023-07-10', '05427', 31, 120 UNION ALL
SELECT '2023-06-27', '05427', 31, 5 UNION ALL
SELECT '2023-06-26', '05427', 31, 6
)
output is
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论