[英]MySQL: Show latest value when using GROUP BY
My table "orders" includes the date_purchased and my table "orders_products" includes the products_id for the specific order. 我的表“ orders”包含购买的日期,我的表“ orders_products”包含特定订单的products_id。
I want to list a specific client's all purchased products_id (not all orders!) showing the latest date_purchased for each products_id. 我想列出特定客户的所有购买的product_id(不是所有订单!),显示每个product_id购买的最新date_purchase。 The list should be ordered with the latest orders_id of these at the top.
该列表应在顶部以最新的orders_id订购。
The code below will show all unique products_id as I want, but the "group by" is resulting in not showing the latest orders_id or date_purchased for each products_id… 下面的代码将根据需要显示所有唯一的products_id,但是“分组依据”导致未显示每个products_id的最新orders_id或date_purchased…
What am I missing here? 我在这里想念什么?
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
The not exists
approach is often the most efficient approach for this type of query: 对于这种类型的查询,
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;
The logic is: "Get me all rows from orders
where there is no row with the same product and a larger id." 逻辑是:“从没有相同产品和更大ID的行的
orders
中获取所有行。” This is equivalent to saying: "Get me the max row". 这相当于说:“让我获得最大的行数”。
For best performance, you want an index on orders(products_id, orders_id)
. 为了获得最佳性能,您需要对
orders(products_id, orders_id)
进行索引。
EDIT: 编辑:
There is another approach that uses subtring_index()
and group_concat()
. 还有另一种使用
subtring_index()
和group_concat()
。 This might be the most efficient way, if the filter on customer_id
is highly selective (that is, greatly reduces the number of rows). 如果
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;
Of course, if the date purchased and orders_id
are both increasing, you can simplify this to using max()
for both: 当然,如果购买日期和
orders_id
都在增加,则可以简化为将max()
用于两者:
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;
Using group by the result will be grouped in un-ordered way you cannot rely on that using group by will give you the latest result in each so for this you need to first get the maximum of purchase date and then join with your orders table with using additional condition in on clause 使用group by结果将以无序方式分组,您不能依赖使用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
This will give the latest orders per products of customer 这将为客户提供每种产品的最新订单
You might try this? 你可以试试这个吗? Cannot test it right now.
目前无法测试。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.