1

我目前无法为我的问题找到解决方案,你们是我最后的希望。两天以来,我一直在尝试解决这个难题:

表项:

----------------------------
| id   | item   | customer |
----------------------------
| 1    | banana | custA    |
----------------------------
| 2    | apple  | custA    |
----------------------------
| 3    | orange | custB    |
----------------------------
| 4    | apple  | custB    |
----------------------------

表供应商价格:

-------------------------------------------------------
| id  |   item    |   price   |   vendor |  timestamp |
-------------------------------------------------------
| 1   |  banana   |   0.23    | VendorA  |  564645564 |
-------------------------------------------------------
| 2   |  orange   |   0.21    | VendorA  |  564645564 |
-------------------------------------------------------
| 3   |  apple    |   0.19    | VendorB  |  564645564 |
-------------------------------------------------------
| 4   |  banana   |   0.22    | VendorB  |  564645565 |
-------------------------------------------------------
| 5   |  banana   |   0.21    | VendorB  |  564645567 |
-------------------------------------------------------

有几点需要注意:

  1. 不是每个供应商都有每件商品
  2. 一些供应商可能会比其他供应商更频繁地更新其价格,从而导致它们之间的时间戳差距更大

例如,我想知道目前哪个供应商以最优惠的价格出售香蕉?

我想我首先需要从每个供应商那里获得每件商品的最新价格,然后按价格对它们进行排序,对吗?但是如何以兼容 MySQL 的方式做到这一点呢?

我认为第一部分的正确方法是:

SELECT MAX(timestamp), vendor, item, MIN(price) FROM vendor_prices WHERE item="banana" GROUP BY vendor;

但是如何将其与所有其他标准联系起来呢?

编辑:我不得不稍微更改第一个表,因为我忘记了问题中的一个重要部分,抱歉:(

预期输出:第一个表(custA 或 custB)中特定客户的所有项目的所有供应商的最新、最优价格

4

1 回答 1

1

您可以为您的条件使用嵌套的分组最大逻辑

select a.*
from vendor_prices a
join (
  select item, min(price) price, max(timestamp) timestamp
  from (
    select d.*
    from vendor_prices d
    join (
      select item, vendor, max(timestamp) timestamp
      from vendor_prices
      group by item, vendor
    ) e using(item, vendor,timestamp )
  ) c
  group by item
) b using (item,price, timestamp)
where a.item = 'banana'

演示

如果您使用的是 Mysql 8+,则可以使用窗口函数受益

编辑 *获取客户的所有商品(每件商品的最佳价格和供应商)*

select  i.*,a.*
from vendor_prices a
join (
  select  item, min(price) price, max(timestamp) timestamp
  from (
    select  d.*
    from vendor_prices d
    join (
      select  item, vendor, max(timestamp) timestamp
      from vendor_prices
      group by item, vendor
    ) e using(item, vendor,timestamp )
  ) c
  group by item
) b using (item,price,timestamp )
join item i using(item)
where i.customer = 'custA'
order by i.item

演示

使用Mysql 8 中可用的窗口函数公用表表达式,您可以使用以下

with latest_price as(
    select *, 
    dense_rank() over (partition by item order by timestamp desc, price asc ) rnk
    from vendor_prices
    order by  item, rnk
)

select i.id itemid, i.customer,a.* 
from latest_price a
join item i using(item)
where i.customer = 'custA'
and a.rnk = 1

演示

于 2018-06-28T19:18:35.450 回答