Используйте `Max ()` с `GROUP BY` в MySQL 5.7 - PullRequest
0 голосов
/ 09 мая 2018

В MySQL 5.7 у меня есть следующие таблицы orders и transactions соответственно. И я хочу получить максимум 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. Выражение № 2 списка SELECT отсутствует в GROUP BY пункт и содержит неагрегированный столбец 'openbank_consentdb.transaction.product', который не является функционально зависит от столбцов в предложении GROUP BY; это несовместимо с sql_mode = only_full_group_by

Я понимаю проблему здесь, SQL не может понять, как GROUP BY, потому что есть несколько категорий. Как записать его так, чтобы он возвращал детали, относящиеся к записям с максимальной отметкой времени для каждого продукта?

Ответы [ 3 ]

0 голосов
/ 09 мая 2018

Я думаю, что вы хотите:

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;

Примечания:

  • Предположительно, все транзакции находятся в правильном порядке, поэтому вам не нужно внешнее соединение.
  • Укажите все имена столбцов, чтобы запрос был однозначным.
  • Не ставьте одинарные кавычки вокруг имен столбцов. Используйте только одинарные кавычки для констант строки и даты.
  • Сюда не входят идентификаторы для транзакций и заказов. Такие идентификаторы не имеют смысла для запроса, возвращающего информацию о продуктах.

EDIT:

Мне приходит в голову, что вы хотите получить полную информацию о транзакции для самой последней транзакции для каждого продукта, который «выполнен». Если это так, я бы пошел на коррелированный подзапрос:

SELECT t.*
FROM transaction t 
WHERE t.timestamp = (SELECT MAX(t2.timestamp)
                     FROM transaction t2 JOIN
                          orders o2
                          ON t2.order_id = o2.idorder 
                     WHERE o2.status = 'done' AND t2.product = t.product
                    ); 
0 голосов
/ 09 мая 2018

Вы можете использовать тот же запрос с простым приемом. При использовании режима sql по умолчанию в mysql 5.7 вы можете использовать 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.

0 голосов
/ 09 мая 2018
 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...