Как этот код SQL выбирает 2 самых дешевых фрукта?

#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 , то строка имеет самую высокую цену. Однако это предположение зависит от базовых данных.

Как я уже сказал, это действительно ужасный способ выполнить эту логику. Изучите функции окна. И используйте разные примеры, чтобы узнать о коррелированных подзапросах.