MySQL:使用GROUP BY时显示最新值

时间:2014-03-17 10:45:56

标签: php mysql greatest-n-per-group

我的表"订单"包括date_purchased和我的表" orders_products"包括特定订单的products_id。

我想列出特定客户的所有购买的products_id(并非所有订单!),显示每个products_id的最新date_purchased。该列表应与最新的orders_id一起订购。

下面的代码会根据我的需要显示所有唯一的products_id,但"组会显示"导致没有为每个products_id ...

显示最新的orders_id或date_purchased

我在这里缺少什么?

SELECT o.orders_id, o.date_purchased, op.products_id

FROM orders o, orders_products op

WHERE o.customers_id = '" . $client_id . "' and op.orders_id = o.orders_id

GROUP BY op.products_id
ORDER BY orders_id DESC

3 个答案:

答案 0 :(得分:2)

not exists方法通常是此类查询的最有效方法:

SELECT o.orders_id, o.date_purchased, op.products_id 
FROM orders o join
     orders_products op
     on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "' and 
      not exists (select 1
                  from orders o2 join
                       orders_products op2
                       on op2.orders_id = o2.orders_id
                  where op2.products_id = op.products_id and
                        o.customers_id = '" . $client_id . "' and
                        o2.orders_id > o.orders_id
                 )
ORDER BY orders_id DESC;

逻辑是:“从orders获取所有行,其中没有包含相同产品和更大ID的行。”这相当于说:“让我获得最大行数。”

为获得最佳效果,您需要orders(products_id, orders_id)上的索引。

编辑:

还有另一种使用subtring_index()group_concat()的方法。如果customer_id上的过滤器具有高度选择性(即大大减少了行数),这可能是最有效的方法。

SELECT max(o.orders_id) as orders_id,
       substring_index(group_concat(o.date_purchased order by orders_id desc), ',', 1) as date_purchased,
       op.products_id 
FROM orders o join
     orders_products op
     on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "'
GROUP BY op.products_id;

当然,如果购买日期和orders_id都在增加,您可以将其简化为使用max()同时使用:{/ p>

SELECT max(o.orders_id) as orders_id,
       max(o.date_purchased) as date_purchased,
       op.products_id 
FROM orders o join
     orders_products op
     on op.orders_id = o.orders_id
WHERE o.customers_id = '" . $client_id . "'
GROUP BY op.products_id;

答案 1 :(得分:0)

按结果使用组将按照无序方式分组,您不能依赖于使用group by将为您提供最新结果,因此您需要首先获得最大购买日期然后加入您的使用on子句

中的附加条件的订单表
SELECT 
  o.orders_id,
  o.date_purchased,
  oo.products_id 
FROM
  orders o
  INNER JOIN (
  SELECT orders.orders_id, MAX(orders.date_purchased) date_purchased ,orders_products.products_id
  FROM orders 
  INNER JOIN   
  orders_products  
  ON(orders_products.orders_id = orders.orders_id)
  GROUP BY orders.orders_id ,orders_products.products_id
  ) oo
   ON( oo.orders_id = o.orders_id AND oo.date_purchased=o.date_purchased)
WHERE o.customers_id = '" . $client_id . "'    
ORDER BY o.orders_id DESC  

这将提供客户每件产品的最新订单

答案 2 :(得分:-1)

你可以尝试一下吗?现在无法测试。

SELECT MAX(o.orders_id), MAX(o.date_purchased), op.products_id

FROM orders o, orders_products op

WHERE o.customers_id = 1 and op.orders_id = o.orders_id

GROUP BY op.products_id