在MySQL 5.7中使用`Max()`和`GROUP BY`

时间:2018-05-09 17:32:13

标签: mysql sql

MySQL 5.7中,我分别有以下orderstransactions表。我想为transaction.timestamp“完成”的每个产品获得最大orders.status

enter image description here

我使用了以下查询:

SELECT 
    MAX(timestamp), 
    product, 
    idorder, 
    idtransaction,
    order_name 
FROM 
    transaction left join orders 
ON 
    transaction.order_id=orders.idorder 
WHERE
    status='done' 
GROUP BY
    'product';

但是它导致了如下错误:

  

错误代码:1055。SELECT列表的表达式#2不在GROUP BY中   子句并包含非聚合列   'openbank_consentdb.transaction.product',这不是功能上的   依赖于GROUP BY子句中的列;这是不相容的   的sql_mode = only_full_group_by

我理解这里的问题,sql无法理解如何GROUP BY,因为有多个类别。如何编写它以便返回与每个产品的最大时间戳记录相关的详细信息?

3 个答案:

答案 0 :(得分:3)

我想你想要:

cli

注意:

  • 据推测,所有交易都是有效订单,因此您不需要外部联接。
  • 限定所有列名称,因此查询是明确的。
  • 不要在列名称周围加上单引号。仅对字符串和日期常量使用单引号。
  • 这不包括交易和订单的ID。这些ID对于返回有关产品的信息的查询没有意义。

编辑:

在我看来,您希望获得每个产品的最新交易的完整交易信息,这些信息是"完成"。如果是这样,我会选择相关的子查询:

SELECT t.product, MAX(timestamp)
FROM transaction t join
     orders o
    ON t.order_id = o.idorder 
WHERE o.status = 'done' 
GROUP BY t.product;

答案 1 :(得分:1)

 select * from ( SELECT 
        MAX(timestamp)timestamp, 
        product
    FROM 
        transaction left join orders 
    ON 
        transaction.order_id=orders.idorder 
    WHERE
        status='done' 
    GROUP BY
        product ) a
   join 

  (SELECT 
        *
    FROM 
        transaction left join orders 
    ON 
        transaction.order_id=orders.idorder 
    WHERE
        status='done' 
 )b on a.timestamp=b.timestamp and a.product=b.product

答案 2 :(得分:0)

您可以通过简单的技巧使用相同的查询。使用mysql 5.7中的默认sql模式,您可以使用ANY_VALUE来绕过该错误。

SELECT 
  MAX(timestamp), 
  product, 
  ANY_VALUE(idorder),
  ANY_VALUE(idtransaction) 
FROM 
  transaction left join orders 
ON 
  transaction.order_id=orders.idorder 
WHERE
  status='done' 
GROUP BY
  'product';

检查文档以详细了解为什么ANY_VALUE在此https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value是必要的。