2015-12-26 2 views
2

На моем веб-сайте я хочу использовать множество разных данных из моей базы данных. В настоящее время я использую четыре запроса для сбора разных данных. Но есть ли способ сделать его более эффективным и помещать в один большой запрос? И как бы я это сделал?PHP/SQL - много запросов SQL

Редактировать: Таким образом, ответ состоял в том, чтобы просто объединить все запросы в один и использовать как можно больше манипуляций с данными в запросах базы данных, а не в php.

$qry = "SELECT COUNT(*) cnt, 
         AVG(level) avg_lvl, 
         SUM(IF(onlinestatus=1, 1, 0)) online_cnt, 
         (SELECT Max(time) FROM refreshes) refresh_time 
         FROM players"; 
       foreach ($db->query($qry) as $row){ 
        $amount_total = $row['cnt']; 
        $average_level = floor($row['avg_lvl']); 
        $online_amount = $row['online_cnt']; 
        $milliseconds = $row['refresh_time'] + 1800000; 
        $update_time = DateTime::createFromFormat('U', intval($milliseconds/1000)); 
       } 
+1

Если между таблицами «rookstayers» и «refreshes» существует общий ключ, вы можете создать sql как «левое внешнее соединение» между таблицами и делать то, что хотите, с одним запросом. Без этого похоже, что это можно сделать в 2-х запросах, потому что 'select * from rookstayers' должно быть достаточно, чтобы манипулировать данными и выполнять любые вычисления, которые вы хотите в php – RamRaider

+0

Итак, в основном просто« SELECT * FROM rookstayers' по первым трем запросам? Затем один для «освежает»? Но дело в том, что у меня также есть такие вещи, как 'WHERE something = something', не будет ли это испортить запрос для тех, которые не используют WHERE ?. У вас есть какой-нибудь пример в «левом внешнем соединении»? –

+0

Да, первый запрос может заменить первые 3 запроса, предложение where может быть протестировано для php, а затем отдельный запрос (если вы не можете присоединиться к таблицам) для данных таблицы refreshes – RamRaider

ответ

1

Вы могли бы объединить все запросы в один, как это:

$qry = "SELECT COUNT(*) cnt, 
      AVG(level) avg_lvl, 
      SUM(IF(onlinestatus=1, 1, 0)) online_cnt, 
      (SELECT Max(time) FROM refreshes) refresh_time 
    FROM rookstayers"; 
foreach ($db->query($qry) as $row){ 
    $amount_total = $row['cnt'] 
    $level = $row['avg_lvl']; 
    $online_amount = $row['online_cnt']; 
    $milliseconds = $row['refresh_time'] + 1800000; 
    $update_time = DateTime::createFromFormat('U', intval($milliseconds/1000)); 
} 

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

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

+0

Недопустимый аргумент, предоставленный foreach() в C: \ xampp \ htdocs \ new \ index.php в строке 32 Всего ластовистов: Примечание: неопределенная переменная: amount_total в C: \ xampp \ htdocs \ new \ index.PHP на линии 40 Средний уровень: Примечание: Undefined переменной: average_level в C: \ XAMPP \ HTDOCS \ Новый \ index.php в строке 41 Rookstayers Online: Notice: Undefined переменной: online_amount в C: \ XAMPP \ HTDOCS \ новый \ index.php в строке 42 Следующее обновление: Примечание: Undefined переменной: update_time в C: \ XAMPP \ HTDOCS \ новый \ index.php в строке 43 Фатальная ошибка: Вызов в формате функции члена () на null в C: \ xampp \ htdocs \ new \ index.php в строке 43 –

+0

Это трудно понять, так как приведенный выше код не имеет этих номеров строк. Ошибки неопределенной переменной должны исходить из вашего кода, а не моего. – trincot

+0

вот скриншот: http://i.imgur.com/xVBFE9E.png –

0

первого и третьего запросов могут быть объединены в одну:

select count(*) as num, sum(onlinestatus = 1) as numOnline 
from rookstayers; 

Второй должен быть агрегации:

select level, count(*) as cnt 
from rookstayers 
group by level; 

В-четвертых, также агрегации; Я не знаю точно, что выглядит как данные, но это, кажется, что-то вроде:

select sum(time + 1800000) 
from refreshes; 

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

EDIT:

Первый, второй и третий могут быть объединены в:

select count(*) as num, sum(onlinestatus = 1) as numOnline, 
     avg(level) as avgLevel 
from rookstayers; 
+0

Как бы я мог получить доступ к этим переменным? Вы назвали их «sum» и «num», «numOnline» и т. Д. ... $ row ['num']? или что. Четвертый - дата/время в миллисекундах. Просто целое число –

+0

@TibiaPlayer. , , Точно так же вы получаете доступ к 'level' и' time'. –

Смежные вопросы