В этом же запросе MySql можно посчитать строку и получить только первую строку? - PullRequest
0 голосов
/ 27 августа 2018

В том же запросе MySql можно посчитать строку и получить только первую строку?

Теперь я использую этот код (и я не знаю, правильно ли):

$query1 = "
SELECT  magni
    FROM  earthquakes
    WHERE  (milli BETWEEN '$data_dal' AND '$data_al')
      AND  (magni BETWEEN '$magn_min' AND '$magn_max')
      AND  (ipoc BETWEEN '$ipo_min' AND '$ipo_max')
      AND  (lati BETWEEN '$lat_inf' AND '$lat_sup')
      AND  (longi BETWEEN '$lng_sin' AND '$lng_des')
    ORDER BY  magni DESC
    LIMIT  1";
$query2 = "
SELECT  COUNT(*)
    FROM  earthquakes
    WHERE  (milli BETWEEN '$data_dal' AND '$data_al')
      AND  (magni BETWEEN '$magn_min' AND '$magn_max')
      AND  (ipoc BETWEEN '$ipo_min' AND '$ipo_max')
      AND  (lati BETWEEN '$lat_inf' AND '$lat_sup')
      AND  ((longi BETWEEN '$lng_sin' AND 180)
              OR  (longi BETWEEN -180 AND '$lng_des')
           )";

$result1 = mysqli_query($con,$query1);
$result2 = mysqli_query($con,$query2);
$array_statistiche = array($result2,$result1);  //numero eventi sismici, magniudo più alta

mysqli_free_result($array_statistiche);
$array_finale= $array_statistiche;

$array_terremoti= json_encode($array_finale); // return value of numero terremoti e array terremoti
mysqli_close($con); // close connection with database

Большое спасибо и извините за мой английский!

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Если вы спрашиваете о дублировании усилий в громоздком WHERE, то это явный победитель:

SELECT SQL_CALC_FOUND_ROWS magni
    FROM earthquakes
    WHERE ...
    ORDER BY  magni DESC
    LIMIT 1;
SELECT FOUND_ROWS();

Первый получает ваш magni, затем продолжает сканировать таблицу, чтобы получить счет. Второй получает это число потокобезопасным способом.

SELECT MAX(magni) ... получает желаемое значение без ORDER BY. Но это не поможет в этой ситуации.

Эти индексы могут помочь ускорить его. Будет использоваться только один, но Оптимизатор выберет какой.

INDEX(magni),
INDEX(milli),
INDEX(lati)

Если вам действительно нужно выполнить только один запрос, который возвращает оба результата, подумайте:

SELECT
    ( SELECT MAX(magni) ... ) AS max_magni,
    ( SELECT COUNT(*)   ... ) AS ct;

То есть объединить оба громоздких запроса в один SELECT. Вы будете повторять WHERE и выполнять одно и то же сканирование дважды.

0 голосов
/ 27 августа 2018

Вам нужно два отдельных запроса, чтобы сделать это в версиях MySQL менее 8+. Но вы всегда можете добавить подзапрос к предложению select вашего запроса лимита, который находит общее количество, что-то вроде этого:

SELECT
    magni,
    (SELECT COUNT(*) FROM earthquakes WHERE ...) AS cnt
FROM earthquakes
WHERE ...
ORDER BY magni DESC
LIMIT 1

Я опустил часть вашего кода отчасти потому, что он не влияет на ответ, а отчасти потому, что я не очень хорошо разбираюсь в том, как написать хорошее утверждение на PHP. Вы должны прочитать о подготовленных выражениях в PHP, потому что обычно вставлять переменные непосредственно в строку запроса - плохая практика.

Если вам интересно, вот как мы могли бы сформулировать вышеуказанный запрос в MySQL 8+, не используя подзапрос, используя COUNT в качестве аналитической функции:

SELECT
    magni,
    COUNT(*) OVER () AS cnt
FROM earthquakes
WHERE ...
ORDER BY magni DESC
LIMIT 1

Вот демонстрационная версия (в SQL Server, наиболее близкое совпадение на момент написания этого ответа), которая показывает эту альтернативу в действии.

Демо

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