Использование подзапроса для сравнения ценового столбца со средней ценой по категориям - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь использовать две таблицы (категории и продукты) для создания таблицы с именами категорий и продуктов. Переменная product_price должна быть прейскурантной ценой, превышающей среднюю цену товара в указанной категории c. Мне нужно использовать подзапрос для создания этой таблицы.

Подзапрос записан в предложении WHERE, в котором сравнивается цена со средней ценой для каждой категории. Кажется, что и главный оператор Select, и подзапрос работают совершенно отдельно. Однако, когда я пытаюсь запустить их полностью, таблица генерирует все цены, а не только те, которые превышают среднюю цену за категорию. Кроме того, когда я использую команду ALL вместо Any, она возвращает только 2 строки для одной категории. Это не возвращает другие 2 строки из других категорий, которые я ожидаю. Есть ли что-то, чего мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 29 февраля 2020

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

SELECT p.product_name, c.category_name, p.list_price
FROM products p 
INNER JOIN categories c ON p.category_id = c.category_id
WHERE p.list_price > (
    SELECT AVG(p1.list_price) FROM products p1 WHERE on p1.category_id = p.category_id     
) 

Коррелированный подзапрос дает вам среднюю цену всех продуктов в той же категории. Это возвращает скалярное значение, поэтому нет необходимости в операторе на основе набора, таком как ALL или ANY.

Также обратите внимание, что ваш исходный запрос имел конфликтующие псевдонимы таблицы между тогда подзапросом и внешним запросом (p и c использовались в обоих контекстах), которые создавали неоднозначность относительно того, к какой таблице относились псевдонимы в подзапросе.

Наконец: если вы выполняете MySQL 8.0 (или версия SQLite, которая поддерживает оконные функции), вы можете получить тот же результат со средним значением окна:

SELECT product_name, category_name, list_price
FROM (
    SELECT 
        p.product_name, 
        c.category_name, 
        p.list_price, 
        AVG(list_price) OVER(PARTITION BY c.category_id) avg_list_price
    FROM products p 
    INNER JOIN categories c ON p.category_id = c.category_id
) t
WHERE list_price > avg_list_price
0 голосов
/ 29 февраля 2020

Вы можете использовать коррелированный подзапрос:

WHERE p.list_price > (SELECT AVG(p2.list_price)
                      FROM products p2
                      WHERE p2.category_id = p.category_id
                     ) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...