【问题标题】:MySQL lowest and latest price per productMySQL 每个产品的最低和最新价格
【发布时间】:2017-12-05 01:02:20
【问题描述】:

我有 3 张桌子

    price_history (Primary: id)
    +----+------------+------+---------+-------+------------+
    | id | id_product | sku  | id_shop | price |  date_add  |
    +----+------------+------+---------+-------+------------+

    | 1  | 11         | 101  | 1001    | 10    | 2017-07-01 |
    | 2  | 12         | 101  | 1002    | 15    | 2017-07-01 |
    | 3  | 13         | 101  | 1003    | 20    | 2017-07-01 |
    | 4  | 11         | 101  | 1001    | 11    | 2017-07-02 | <-- lowest latest

    | 5  | 14         | 102  | 1001    | 45    | 2017-07-01 |
    | 6  | 15         | 102  | 1002    | 45    | 2017-07-01 |
    | 7  | 16         | 102  | 1003    | 45    | 2017-07-01 | <-- shop 1003 is the lowest,
    latest among shops and should not be display, because the shop monitored is 1001
    | 8  | 15         | 102  | 1002    | 60    | 2017-07-02 | 
    | 9  | 14         | 102  | 1001    | 55    | 2017-07-02 | 

    |10  | 17         | 103  | 1001    | 90    | 2017-07-01 |
    |11  | 18         | 103  | 1002    | 90    | 2017-07-01 |
    |12  | 19         | 103  | 1003    | 90    | 2017-07-01 |
    |13  | 17         | 103  | 1001    | 100   | 2017-07-02 | <-- lowest latest 
    |14  | 18         | 103  | 1002    | 100   | 2017-07-02 |
    |15  | 19         | 103  | 1003    | 100   | 2017-07-02 |
    +----+------------+------+---------+-------+------------+

    product (primary: id_product)
    +------------+---- ---+-----+--------------+---------+
    | id_product | active | sku | product_name | id_shop |
    +------------+--------+-----+--------------+---------+
    | 11         | 1      | 101 | Red          | 1001    |
    | 12         | 1      | 101 | A bit red    | 1002    |
    | 13         | 1      | 101 | Very red0    | 1003    |
    | 14         | 1      | 102 | Blue         | 1001    |
    | 15         | 1      | 102 | A bit blue   | 1002    |
    | 16         | 1      | 102 | Very blue    | 1003    |
    | 17         | 1      | 103 | Green        | 1001    |
    | 18         | 1      | 103 | A bit green  | 1002    |
    | 19         | 1      | 103 | Very green   | 1003    |
    | 20         | 0      | 104 | Discontinued | 1001    |
    | 21         | 0      | 104 | Out of stock | 1002    |
    | 22         | 0      | 104 | Varnish      | 1003    |
    +------------+--------+-----+--------------+---------+

    shop (primary: id_shop)
    +---------+--------+
    | id_shop | name   |
    +---------+--------+
    | 1001    | Shop A |
    | 1002    | Shop B |
    | 1003    | SHop C |
    +---------+--------+

每家商店都有不同的产品名称,但都有国际编号 (sku)。

要监控的 ID 店铺:1001(店铺 A)

已经在 stackoverflow 中搜索,但我找不到正确的。 我怎样才能获得每个 sku 的最低和最新价格。 我还是新手,不懂子选择

这是我目前所做的

    SELECT pph.id, s.name, h2.price, h2.sku
    FROM (
        SELECT MAX(h.id) max_id, MIN(h.price) min_price, h.id, h.id_shop
        FROM price h
        GROUP BY sku
    ) pph 
    LEFT JOIN price h2 ON (h2.id = max_id)
    LEFT JOIN shop s ON (s.id_shop = pph.id_shop)

那么最后我只需要显示被监控的商店,'Shop A'

预期结果:

    +----+------------+------+---------+-------+
    | id | id_product | sku  | id_shop | price | 
    +----+------------+------+---------+-------+
    | 4  | 11         | 101  | 1001    | 11    |
    |13  | 17         | 103  | 1001    | 100   |
    +----+------------+------+---------+-------+ 

sku 102的最低价格是shop 1003,所以我们不需要展示他们。

JSFiddle http://sqlfiddle.com/#!9/ba3a2

谢谢

需要帮助,仍未找到解决方案

【问题讨论】:

  • 也显示您的预期结果
  • @JYoThI 预期结果已添加
  • @Gurwinder Singh 是的,你是对的。 date_add 已添加
  • @Gurwinder Singh 第二个标志 102 &lt;-- lowest latest 已更正。你的眼睛像鹰一样锐利......

标签: mysql sql


【解决方案1】:

您可以使用带有限制子句的相关子查询来简单地实现这一点:

select *
from price_history h
where id_shop = 1001
and id = (select id
          from price_history p
          where h.sku = p.sku
          and h.id_shop = p.id_shop
          order by date_add desc, price asc
          limit 1
          );

以上是简单的解决方案,但可能会遇到较大数据集的性能问题。

您可以使用以下基于联接的解决方案:

select *
from price_history
join (
    select sku, date_add, min(price) as price
    from price_history
    join (
        select sku, max(date_add) as date_add
        from price_history
        where id_shop = 1001
        group by sku
    ) t using (sku, date_add)
    where id_shop = 1001
    group by sku, date_add
) t using (sku, date_add, price)
where id_shop = 1001

select *
from price_history
join (
    select sku, date_add, id_shop, min(price) as price
    from price_history
    join (
        select sku, id_shop, max(date_add) as date_add
        from price_history
        where id_shop = 1001
        group by sku, id_shop
    ) t using (sku, date_add, id_shop)
    group by sku, date_add, id_shop
) t using (sku, date_add, price, id_shop);

Demo

【讨论】:

  • 这可能是最简单的。我怀疑嵌套的不相关子查询会更快。
  • @Strawberry - 是的。我添加了基于联接和子查询的解决方案。
  • @Gurwinder Singh 更正了第二个 price_history sku 102 &lt;-- shop 1003 is the lowest, latest among shops and should not be display, because the shop monitored is 1001
  • @inMILD 最低的那一行是怎么回事?不应该选择最新日期和然后最低价格的行吗?我想我还是没有完全理解你的逻辑。
  • @GurwinderSingh 由于shop 1003没有为sku 102添加新价格,所以他是其他商店中价格最低的,他的价格是他自己最新的。
【解决方案2】:

这将为您提供每个 sku 最多 date_add 的商店

SELECT sku, MAX(date_add)
FROM price_history
WHERE id_shop = 1001
GROUP BY sku;

然后您可以将其包装到另一个查询中并再次将 JOINprice_history 包装起来,以获得结果,例如:

SELECT ph.id, ph.id_product, ph.sku, ph.id_shop, ph.price
FROM proce_history ph JOIN (
 SELECT sku, MAX(date_add) AS `date_add`
 FROM price_history
 WHERE id_shop = 1001
 GROUP BY sku
) a ON ph.sku = a.sku AND ph.date_add = a.date_add;

【讨论】:

  • @inMILD 那么,在您的示例中,11 是最新的但不是最低的?
  • 哪 11 个? id_product 还是 id?
  • @inMILD 您需要表格中的时间戳列。它将解决问题。我有一个问题要问你,你说它是最低的依据是什么,而这个值是最新的。所以你需要时间戳列
  • 然后每个 sku 的时间戳的最小值和时间戳的最大值
  • @karan arora date_add 已添加
猜你喜欢
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 2016-05-09
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多