Будет ли механизм SQL использовать какой-либо подход, кроме перебора, в этом запросе? - PullRequest
0 голосов
/ 16 октября 2018

Приведенный ниже запрос извлекает медианное значение LAT_N из таблицы STATION, находя запись, в которой число LAT_N значений, больших, чем он сам, равно тем, которые меньше его самого.

SELECT ROUND(S.LAT_N, 4) AS MEDIAN FROM STATION S WHERE 
(SELECT COUNT(LAT_N) FROM STATION WHERE LAT_N < S.LAT_N) = 
(SELECT COUNT(LAT_N) FROM STATION WHERE LAT_N > S.LAT_N)

Это умное решение, которое кто-то другой опубликовал в качестве решения вопроса Хакерранка, но мне интересно, как именно SQL-механизм подойдет к этому.

Будет ли такая необычная структура запроса вызывать только грубое форсирование двух подзапросов до тех пор, пока их COUNT не станут равными, или есть простая возможность для оптимизации, которую я упускаю?

(Я понимаю, что этот запрос не предоставляет медиану в каждом случае. Я только после объяснения того, будет ли механизм SQL пытаться оптимизировать его до любого уровня лучше, чем перечисление методом "грубой силы" для каждого подзапроса).

1 Ответ

0 голосов
/ 16 октября 2018

Это не «умное» решение.Это умно, но это не полностью решает проблему.Например, он не работает для четного числа строк.

Вероятно, самый безопасный метод - это переменные:

SELECT ROUND(AVG(S.LAT_N), 4) AS MEDIAN
FROM (SELECT S.*, (@rn := @rn + 1) as seqnum
      FROM (SELECT S.* FROM STATION S ORDER BY S.LAT_N) S CROSS JOIN
           (SELECT @rn := 0) params
     ) S
WHERE 2 * seqnum IN (@rn, @rn + 1, @rn + 2) ;

Это должно работать независимо от количества строк или распределенияценности.Есть еще один умный метод, который использует GROUP_CONCAT(), но его полезность ограничена максимальной длиной промежуточного результата GROUP_CONCAT().

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