从 3 个表中选择,在两个 group by 之前有两个 order by

Posted

技术标签:

【中文标题】从 3 个表中选择,在两个 group by 之前有两个 order by【英文标题】:Select from 3 tables with two order by before two group by 【发布时间】:2015-11-13 06:49:03 【问题描述】:

我尝试获取每个最新和最低报价的产品列表

餐桌产品

id | name

餐桌优惠

id | product_id | price | created | dealer_id

表格无效

id | offer_id | status

我试过了:

SELECT * FROM product INNER JOIN 
    (
        SELECT offer.product_id , offer.price
        FROM offer 
        LEFT JOIN invalids 
        ON offer.id = invalids.offer_id 
        WHERE invalids.id IS NULL 
        GROUP BY offer.dealer_id
        ORDER BY offer.created DESC
    ) o 
ON o.product_id = product.id 
ORDER BY product.name

我已尝试使用此优惠值的 sqlfiddle http://sqlfiddle.com/#!9/32658/3:

(`id`, `price`, `dealer_id`, `product_id`, `created`)  
(1,12.60,1,1,'2015-05-17 08:44:45'),  
(2,13.00,1,1,'2015-08-17 08:44:45'),  
(3,20.00,1,1,'2015-08-17 08:45:30'),  
(4,10.00,1,1,'2015-08-17 08:45:46'),  
(5,4.00,2,1,'2015-05-17 08:44:11'),  
(6,11.00,2,1,'2015-08-17 08:44:46'),  
(7,5.00,2,1,'2015-08-17 08:45:31'),  
(9,110.00,2,2,'2015-08-17 08:46:58'),  
(10,11.00,2,2,'2015-08-17 08:47:12');  

产品 ID 1 的预期值是商品 ID 7 和价格 5。

我认为我必须意识到这些步骤:

    created 订购优惠并按dealer_id 分组以获得最新条目 从第 1 步获取结果并按价格排序以获得最低价格。 为所有产品制作这个

也许我必须使用第二个 SELECT FROM offerGROUP BYORDER BY 但我如何从第一个(外部)选择中获得 product_id

【问题讨论】:

产品 1 的最新报价是 id 4,而不是 id 7。您想要最新报价还是最低报价?如果您想要最低的报价,为什么不使用价格为 4 的 id 5 呢?我不明白。 为什么不提供5胜?这是4美元和更早的时间?是不是因为您想要经销商/产品的最新报价(每个 1 个),然后选择其中最低的价格(从而选择经销商/价格)? 【参考方案1】:

这个查询应该可以帮助你:

SELECT * 
FROM product
JOIN (
  SELECT product_id, min(price) as minPrice, max(created) as newestOffer 
  FROM offer
  WHERE id NOT IN (SELECT offer_id FROM invalids)
  GROUP BY 1
) as b
ON product.id = b.product_id

【讨论】:

MIN(date) 将为您提供最旧的报价,而不是最新的报价。【参考方案2】:

我会首先获取每个产品报价的最新日期,如下所示:

SELECT product_id, MAX(created) AS latestOffer
FROM offer
GROUP BY product_id;

一旦你有了它,你就可以将它加入到原始表中以获得该优惠:

SELECT o.*
FROM offer o
JOIN(
   SELECT product_id, MAX(created) AS latestOffer
   FROM offer
   GROUP BY product_id) tmp ON tmp.product_id = o.product_id AND tmp.latestOffer = o.created;

这是一个SQL Fiddle 示例。

【讨论】:

【参考方案3】:

根据我理解你的目标在黑暗中拍摄......

很多嵌套的子查询.. 不断思考必须有更好的方法...

SELECT OO.ID, OO.Price, OO.Dealer_Id, OO.Product_ID, OO.created, P.name 
FROM Offer OO
INNER JOIN (
  SELECT Min(Price) as MinP
  FROM offer O
  INNER JOIN (
    SELECT max(OI.created) as LatestOffer, OI.Dealer_ID, OI.Product_ID 
    FROM  Offer OI
    LEFT JOIN invalids I
     on OI.Id = I.offer_Id
    WHERE I.ID is null
    GROUP BY OI.Dealer_Id, OI.Product_Id
   ) B
   on O.Dealer_Id = B.Dealer_Id
  and O.Product_Id = B.Product_Id
  and O.Created = B.LatestOffer
  ) Z
 on OO.Price = Z.MinP
INNER JOIN product P 
 on P.ID = OO.Product_ID

SQL FIDDLE

【讨论】:

以上是关于从 3 个表中选择,在两个 group by 之前有两个 order by的主要内容,如果未能解决你的问题,请参考以下文章

使用 group by 从一个包含批量记录的表中获取一些统计数据并将结果放入第二个表中

GROUP BY 从历史表中检索最后一个事件

使用 GROUP BY 从多个表中选择

mysql连接3个表与group by group by

SQL GROUP BY/COUNT 即使没有结果

如何从表中选择带有 oracle sql 中的 group by 子句的嵌套 json 对象?