You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中创建查询仓库库存日环比低于20%商品的视图

解决方法:创建库存占比低于20%的商品视图

没问题,我来帮你搞定这个需求!核心思路是先获取每个商品在对应仓库中前一日的库存数量,再计算当日库存与前一日的占比,最后筛选出占比低于20%的记录并封装成视图。

前提假设

根据你提供的表结构截图,我假设你的数据库中有以下核心表(如果表名/字段名不同,直接替换即可):

  • inventory:库存记录表,包含warehouse_id(仓库ID)、product_id(商品ID)、stock_date(库存日期)、stock_quantity(库存数量)
  • warehouse:仓库信息表,包含warehouse_id、warehouse_name(仓库名称)
  • product:商品信息表,包含product_id、product_name(商品名称)

方法一:使用LATERAL JOIN(适合PostgreSQL等支持的数据库)

这种方式可以精准匹配前一日的库存记录,避免日期不连续的问题:

CREATE VIEW low_stock_ratio_products AS
SELECT
    w.warehouse_name,
    p.product_name,
    i.stock_date,
    i.stock_quantity AS current_stock,
    prev_stock.stock_quantity AS previous_stock,
    ROUND((i.stock_quantity::FLOAT / prev_stock.stock_quantity), 4) AS stock_ratio
FROM
    inventory i
-- 关联获取同一仓库、同一商品的前一日库存
JOIN LATERAL (
    SELECT stock_quantity
    FROM inventory
    WHERE warehouse_id = i.warehouse_id
      AND product_id = i.product_id
      AND stock_date = i.stock_date - INTERVAL '1 day'
) prev_stock ON TRUE
-- 关联仓库表获取名称
JOIN warehouse w ON i.warehouse_id = w.warehouse_id
-- 关联商品表获取名称
JOIN product p ON i.product_id = p.product_id
-- 筛选条件:前一日库存不为0,且当日库存占比低于20%
WHERE
    prev_stock.stock_quantity > 0
    AND (i.stock_quantity::FLOAT / prev_stock.stock_quantity) < 0.2
ORDER BY
    i.stock_date DESC,
    w.warehouse_name,
    p.product_name;

方法二:使用窗口函数LAG()(适合MySQL 8.0+、PostgreSQL、SQL Server等)

如果你的数据库支持窗口函数,这种写法更简洁:

CREATE VIEW low_stock_ratio_products AS
WITH inventory_with_prev_stock AS (
    SELECT
        warehouse_id,
        product_id,
        stock_date,
        stock_quantity,
        -- 按仓库+商品分区,按日期排序,获取前一条记录的库存
        LAG(stock_quantity) OVER (PARTITION BY warehouse_id, product_id ORDER BY stock_date) AS previous_stock
    FROM inventory
)
SELECT
    w.warehouse_name,
    p.product_name,
    inv.stock_date,
    inv.stock_quantity AS current_stock,
    inv.previous_stock,
    ROUND((inv.stock_quantity::FLOAT / inv.previous_stock), 4) AS stock_ratio
FROM inventory_with_prev_stock inv
JOIN warehouse w ON inv.warehouse_id = w.warehouse_id
JOIN product p ON inv.product_id = p.product_id
WHERE
    inv.previous_stock IS NOT NULL -- 排除没有前一日数据的初始记录
    AND inv.previous_stock > 0 -- 避免除以0错误
    AND (inv.stock_quantity::FLOAT / inv.previous_stock) < 0.2
ORDER BY
    inv.stock_date DESC,
    w.warehouse_name,
    p.product_name;

注意事项

  • 请根据实际表名/字段名替换代码中的对应名称,比如如果库存表叫stock_records,直接替换即可。
  • 转换为FLOAT是为了避免整数除法导致的错误(比如整数1除以5会得到0,而不是0.2)。
  • 如果你的日期字段是DATE类型,INTERVAL '1 day'可能需要调整为对应数据库的语法(比如MySQL用DATE_SUB(i.stock_date, INTERVAL 1 DAY))。

内容的提问来源于stack exchange,提问作者k_dadun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:50:39