在此查询中,SQL引擎会使用暴力破解以外的其他方法吗?

时间:2018-10-15 22:13:35

标签: mysql sql database

下面的查询通过查找LAT_N值大于其自身的数量等于小于其自身的值的记录,从STATION表中检索LAT_N的中值。 / p>

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)

这是一个聪明的解决方案,其他人将其发布为Hackerrank问题的解决方案,但我想知道SQL引擎将如何解决这个问题。

这种不寻常的查询结构是否只需要对两个子查询进行强行强制,直到它们的COUNT相等,或者缺少一个容易实现的优化机会?

(我知道此查询不会在任何情况下都提供中位数。我只是在说明SQL引擎是否会尝试将其优化到比每个子查询的蛮力枚举更好的水平)

1 个答案:

答案 0 :(得分:0)

这不是“智能”解决方案。它很聪明,但是并不能完全解决问题。例如,它对于偶数行不起作用。

最安全的方法可能是变量:

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()中间结果的最大长度。