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

无起止日期如何查询历史价格?SQL查询筹款最少产品遇价格表问题

问题1:不指定起止日期查询历史价格

这种场景下你的价格表应该是按生效日期存储价格变动记录的,对吧?每条记录只存价格开始生效的日期,结束日期其实就是下一次价格变动的起始日期(最新价格则没有明确结束日期)。这里有两种实用方法:

方法1:用窗口函数LEAD()获取价格有效区间

假设你的价格表叫price_history,结构为product_id, effective_date, price。用LEAD()可以直接拿到同产品下一条价格记录的生效日期,作为当前价格的结束边界:

SELECT
  product_id,
  effective_date AS start_date,
  -- 最后一条记录(无后续价格变动)的结束日期设为当前日期或NULL,根据需求调整
  LEAD(effective_date) OVER (PARTITION BY product_id ORDER BY effective_date) AS end_date,
  price
FROM price_history
ORDER BY product_id, effective_date;

这样就能得到每个价格的完整有效区间,不用手动指定起止日期。如果要匹配订单对应的历史价格,只需把订单表和这个结果关联,判断order_date落在start_date和end_date之间即可(注意处理end_date为NULL的情况,代表该价格当前仍生效)。

方法2:自连接匹配下一次价格变动日期

如果你的数据库不支持窗口函数(比如老版本MySQL),可以用自连接实现:

SELECT
  ph1.product_id,
  ph1.effective_date AS start_date,
  MIN(ph2.effective_date) AS end_date,
  ph1.price
FROM price_history ph1
LEFT JOIN price_history ph2
  ON ph1.product_id = ph2.product_id
  AND ph2.effective_date > ph1.effective_date
GROUP BY ph1.product_id, ph1.effective_date, ph1.price
ORDER BY ph1.product_id, ph1.effective_date;

原理是找到同产品中比当前生效日期晚的最小日期,作为当前价格的结束日期,同样用NULL标记最新生效的价格。


问题2:找出筹款金额最少的产品

首先明确:筹款金额应该是每个产品在各价格区间的订单数量×对应价格的总和。我们需要把订单表和价格有效区间关联,计算总金额后取最小值。

假设你有三张核心表:

  • products:product_id, product_name(可选,用于显示产品名称)
  • price_history:product_id, effective_date, price
  • orders:order_id, product_id, order_date, quantity

完整查询语句

SELECT
  p.product_id,
  p.product_name,
  -- 用COALESCE处理无订单的产品,总金额设为0
  COALESCE(SUM(o.quantity * ph.price), 0) AS total_fundraising
FROM products p
LEFT JOIN orders o ON p.product_id = o.product_id
LEFT JOIN (
  -- 先获取每个价格的有效区间
  SELECT
    product_id,
    effective_date,
    LEAD(effective_date) OVER (PARTITION BY product_id ORDER BY effective_date) AS end_date,
    price
  FROM price_history
) ph
  ON o.product_id = ph.product_id
  AND o.order_date >= ph.effective_date
  AND (ph.end_date IS NULL OR o.order_date < ph.end_date)
GROUP BY p.product_id, p.product_name
ORDER BY total_fundraising ASC
LIMIT 1; -- 取筹款最少的产品

如果你的表结构和假设不同(比如订单表没有quantity字段,默认按1计算),只需调整对应计算逻辑即可。如果不需要包含无订单的产品,把LEFT JOIN orders改成JOIN orders即可。


内容的提问来源于stack exchange,提问作者Daniel Esteban Ladino Torres

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:34:19