dongyo7931 2014-03-17 10:45
浏览 76
已采纳

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

My table "orders" includes the date_purchased and my table "orders_products" includes the products_id for the specific order.

I want to list a specific client's all purchased products_id (not all orders!) showing the latest date_purchased for each products_id. The list should be ordered with the latest orders_id of these at the top.

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…

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
  • 写回答

3条回答 默认 最新

  • drexlz0623 2014-03-17 12:23
    关注

    The not exists approach is often the most efficient approach for this type of query:

    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." This is equivalent to saying: "Get me the max row".

    For best performance, you want an index on orders(products_id, orders_id).

    EDIT:

    There is another approach that uses subtring_index() and 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).

    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:

    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;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?