MySQL - найдите минимальную цену, используя соединение - PullRequest
1 голос
/ 25 марта 2011

У меня есть таблица примерно так:

order_id INT product_id INT средний_ценный DOUBLE other_price DOUBLE

Существует несколько product_ids на order_id, то есть несколько продуктов на заказ. Я хочу продукт с минимальной средней ценой за заказ и из этих продуктов те, для которых other_price >= average_price.

Я пробовал это:

SELECT a.order_id, a.product_id, a.average_price, a.other_price
FROM
    (SELECT order_id, product_id, min(average_price) as average_price
     FROM orders
     GROUP BY order_id
    ) as min_priced_product_per_order
JOIN orders AS a ON a.order_id = min_priced_product_per_order.order_id and min_priced_product_per_order.product_id = min_priced_product_per_order.product_id 
WHERE a.other_price >= a.average_price

Но результаты не те, что я ожидал, я не уверен, что получаю product_id с минимальной средней ценой за каждый заказ (я подтвердил, осмотрев БД).

Можете ли вы предложить лучший запрос?

Приветствие.

Пит

1 Ответ

0 голосов
/ 25 марта 2011

Ключ к вашей проблеме в том, что product_id просто не работает ни с группировкой, ни с агрегатной функцией (этот запрос не будет выполняться в большинстве RDMS).

(SELECT order_id, product_id, min(average_price) as average_price
     FROM orders
     GROUP BY order_id
) as min_priced_product_per_order

Это отличное расширение, созданное MySQL, чтобы избежать определенных объединений, требующих подзапросов, которые в прошлом он не поддерживал. product_id выбирается произвольно, т. е. в какой бы строке он ни находился первым без особой причины. Это, безусловно, не будет (ну может случайно) вернуть результаты, которые вы хотели бы, если вы ищете определенный product_id. http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html

Вы всегда можете написать такие запросы, отбросив идентификатор-нарушитель (product_id) из агрегата во внутреннем запросе, а затем присоединиться к вашему значению агрегата в этом случае min (average_price) во внешнем запросе, чтобы найти идентификатор.

(SELECT min_order.order_id, product_id, min_order.average_price
FROM
(SELECT order_id, min(average_price) as average_price
     FROM orders
     GROUP BY order_id
 ) AS min_order
 JOIN orders on 
    min_order.product_id = order.product_id
    AND min_order.average_price = order.average_price

Примечание: это вернет все минимальные средние_продукты_идентификатора продукта, если есть связь. Что для меня кажется правильным, иначе вы просто выбираете один продукт произвольно, а это не то, чем должен быть SQL. Но вы можете снова отфильтровать результаты, обернув другой агрегат вокруг вышеуказанного запроса, а затем выбрать минимальный или максимальный идентификатор продукта, чтобы убедиться, что вы получите только один результат на заказ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...