#mysql #sql
#mysql #sql
Вопрос:
У меня есть этот SQL-код, который я получил отсюда. Я не могу понять, как это работает.
SELECT type, variety, price
FROM fruits
WHERE ( SELECT COUNT(*)
FROM fruits AS f
WHERE f.type = fruits.type AND f.price <= fruits.price
) <= 2
Таблицу можно найти по ссылке, упомянутой выше, или вы можете нажать здесь, код также можно найти по этой ссылке
Комментарии:
1. (а) не очень эффективно, (б) выбирая только те фрукты, у которых есть 2 или меньше фруктов (включая их самих), которые имеют ту же или более низкую цену (опечатка?)
2. да, я неправильно понял это, я сразу же внесу исправления в вопрос!
Ответ №1:
Во-первых, это не так. Чтобы получить самый дорогой, потребуется подзапрос f.price >= fruits.price
. Это становится самым дешевым. Но позвольте мне предположить, что это то, что вы намереваетесь.
Логика, которую он реализует, действительно довольно сложна. Но вот несколько сценариев:
- Если два самых дорогих фрукта для данного вида имеют уникальные цены, то он делает то, что вы хотите.
- Если ровно два фрукта стоят дороже всего, то их возвращают.
- Если 3 или более фруктов считаются самыми дорогими для данного типа, то он ничего не возвращает.
Есть гораздо лучшие способы выразить эту логику, используя dense_rank()
или row_number()
, в зависимости от фактического намерения.
Как работает запрос? Подзапрос является коррелированным подзапросом. Способ думать об этом заключается в том, что для каждой строки во внешнем запросе выполняется внутренний запрос. Внутренний запрос подсчитывает количество фруктов одного и того же типа с учетом условия цены — количество с той же или более высокой ценой. Обратите внимание, что механизм SQL может использовать другой план выполнения.
Предполагается, что если возвращается подзапрос 1
, то строка имеет самую высокую цену. Однако это предположение зависит от базовых данных.
Как я уже сказал, это действительно ужасный способ выполнить эту логику. Изучите функции окна. И используйте разные примеры, чтобы узнать о коррелированных подзапросах.