MySQL LEFT JOIN,GROUP BY和ORDER BY不按要求工作

时间:2011-01-02 20:56:07

标签: mysql

我有一张桌子

'products' => ('product_id', 'name', 'description') 

和一个表

'product_price' => ('product_price_id', 'product_id', 'price', 'date_updated')

我想执行类似

的查询
SELECT `p`.*, `pp`.`price` 
FROM `products` `p` 
LEFT JOIN `product_price` `pp` ON `pp`.`product_id` = `p`.`product_id`
GROUP BY `p`.`product_id` 
ORDER BY `pp`.`date_updated` DESC

你可能经常猜测价格会经常变化,我需要拿出最新的价格。麻烦的是我无法弄清楚如何订购LEFT JOINed表。我尝试使用MAX()之类的一些GROUP BY函数,但这只会拉出列而不是行。

感谢。

4 个答案:

答案 0 :(得分:16)

在GROUP BY摘要中使用ORDER BY似乎不可能。我的基本逻辑是有缺陷的。我需要运行以下子查询。

SELECT `p`.*, `pp`.`price` FROM `products` `p` 
LEFT JOIN (
    SELECT `price` FROM `product_price` ORDER BY `date_updated` DESC
) `pp` 
ON `p`.`product_id` = `pp`.`product_id`
GROUP BY `p`.`product_id`;

这会影响性能,但因为每行都有相同的子查询,所以不应该太糟糕。

答案 1 :(得分:1)

您需要正确设置别名,并设置您正在加入的内容:

SELECT p.*, pp.price 
FROM products AS p 
LEFT JOIN product_price AS pp
ON pp.product_id = p.product_id 
GROUP BY p.product_id 
ORDER BY pp.date_updated DESC

答案 2 :(得分:-1)

这将为您提供最后更新的价格:

select
  p.*, pp.price
from
  products p,
  -- left join this if products may not have an entry in prodcuts_price
  -- and you would like to see a null price with the product
  join 
  (
      select 
        product_price_id, 
        max(date_updated) 
      from products_price
      group by product_price_id
   ) as pp_max
    on p.product_id = pp.product_id
  join products_price pp on 
    pp_max.prodcuts_price_id = pp.products_price_id

答案 3 :(得分:-2)

Mysqlism:

SELECT p.*, MAX(pp.date_updated), pp.price 
FROM products p 
LEFT JOIN product_price pp ON pp.product_id = p.product_id
GROUP BY p.product_id 

将在某些RDBMS上运行:

SELECT p.*, pp.date_updated, pp.price 
FROM products p 
LEFT JOIN product_price pp ON pp.product_id = p.product_id
WHERE (p.product_id, pp.date_updated) 

   in (select product_id, max(date_updated) 
       from product_price 
       group by product_id)

适用于大多数RDBMS:

SELECT p.*, pp.date_updated, pp.price 
FROM products p 
LEFT JOIN product_price pp ON pp.product_id = p.product_id

WHERE EXISTS
(
    select null -- inspired by Linq-to-SQL style :-)
    from product_price 

    WHERE product_id = p.product_id 

    group by product_id

    HAVING max(date_updated) = pp.date_updated
)

将适用于所有RDBMS:

SELECT p.*, pp.date_updated, pp.price 
FROM products p 
LEFT JOIN product_price pp ON pp.product_id = p.product_id

LEFT JOIN 
(
    select product_id, max(date_updated) as recent 
    from product_price 
    group by product_id
) AS latest 
ON latest.product_id = p.product_id AND latest.recent = pp.date_updated

如果 nate c 的代码意图是从product_price获取一行,则不需要 table-derive (即join (select product_price_id, max(date_updated) from products_price) as pp_max),也可以简化(即不需要使用product_price_id代理主键),如下所示:

SELECT p.*, pp.date_updated, pp.price 
FROM products p 
LEFT JOIN product_price pp ON pp.product_id = p.product_id
WHERE pp.date_updated = (select max(date_updated) from product_price)