Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: оптимизировать запрос

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
exlant
Отправлено: 10 Февраля, 2015 - 05:51:02
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




есть две таблицы
В таблице event хранятся события, и есть колонки id,name,start,end;
в event_days_of_week есть id_event, Monday, Tuesday, Wednesday, Thursday, Friday, Suturday, Sunday

в start и end содержатся дата начала и дата конца события
в названиях недели содержится числа для сортировки, и если в каком то дне недели стоит 0, нам нужно его пропустить.

собственно нужно выбрать все события в диапазоне сегодняшний день + 28 дней, не выбирать событие в день недели, в котором у него стоит 0, и отсортировать по дням недели.
На выходе должны получить такой массив:
$array[дата_дня][индекс событий,которые вошли в этот день 0,1,2,3 и т.д.][свойства этого события id,name,start,date]

я выбираю события через цикл средствами php
PHP:
скопировать код в буфер обмена
  1.  
  2. for($a=0;$a<28;$a++){
  3.         $day_of_week = date('l',  mktime(0,0,0, date('m'),date('d')+$a, date('Y')));
  4.         $date = date('Y-m-d',  mktime(0,0,0, date('m'),date('d')+$a, date('Y')));
  5.         $query = 'SELECT e.id,e.name FROM event e '
  6.                 . 'INNER JOIN event_days_of_week d ON d.event_id=e.id '
  7.                 . 'WHERE e.start <= ADDDATE(CURDATE(),?) AND e.end >= ADDDATE(CURDATE(),?) '
  8.                 . 'AND d.'.$day_of_week.' != 0 '
  9.                 . 'ORDER BY d.'.$day_of_week
  10.                 ;
  11.         $array = array('ii',$a,$a);
  12.         $result[$date] = $this->get_data($query, 'assoc', $array);
  13.         }
  14.         var_dump($result);
  15.  

можно ли как то это оптимизировать, что бы не делать столько запросов к базе?

(Отредактировано автором: 10 Февраля, 2015 - 05:54:06)

 
 Top
KingStar
Отправлено: 10 Февраля, 2015 - 11:46:18
Post Id



Участник


Покинул форум
Сообщений всего: 1889
Дата рег-ции: Авг. 2011  
Откуда: Беларусь


Помог: 69 раз(а)




условие составить в цикле, а сам запрос вынести из цикла, дату через BETWEEN


-----
То что программа работает, не означает что она написана правильно!
 
 Top
exlant
Отправлено: 10 Февраля, 2015 - 13:44:37
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




KingStar пишет:
условие составить в цикле, а сам запрос вынести из цикла, дату через BETWEEN


а как составить это условие в цикле? если бы я знал как, я бы не спрашивал...
и по поводу BETWEEN, читал на каком то сайте что лучше через больше меньше, так быстрее выходит
 
 Top
KingStar
Отправлено: 10 Февраля, 2015 - 13:59:30
Post Id



Участник


Покинул форум
Сообщений всего: 1889
Дата рег-ции: Авг. 2011  
Откуда: Беларусь


Помог: 69 раз(а)




вообще не понимаю, зачем здесь цикл
у тебя количество дней от 0 до 28
дату выбираешь от текущей, до +28 и день недели != 0

то, что ты сейчас делаешь - это ищешь на каждый день 0123....28
а это равносильно что искать на весь промежуток 0-28


-----
То что программа работает, не означает что она написана правильно!
 
 Top
exlant
Отправлено: 10 Февраля, 2015 - 15:38:29
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




а мне вот и надо промежуток от 0 - 28 (0-28 это условно это будут скорей всего переменные)

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

имеем строчки id = 1, name = event, start = 2015.02.10, end 2015.03.15, Monday = 1, Tuesday = 2, Wednesday = 2, Thursday = 0, Friday = 2, Suturday = 0, Sunday = 0, и строчку №2 id = 2, name = event_2, start = 2015.02.11, end 2015.04.15, Monday = 2, Tuesday = 3, Wednesday = 1, Thursday = 1, Friday = 0, Suturday = 1, Sunday = 1

вот это все мне нужно вывести так, что бы на сегодняшний день вторник вывелось только первое событие, на второй день - среда вывелось первое и второе событие(при том, что бы с начало было второе событие, то есть ORDER BY Wednesday), через день -четверг вывелось только второе событие, и т.д.... а потом с этого всего составить таблицу по дням недели - Пн, Вт,СР.. и т.д. допустим на 4ре недели вперед.

Про циклы в mysql очень мало информации, и из того что я понял, они доступны только из консоли, или нужно как то делать, через процедуры.

Мне бы хотя бы один рабочий примерчик, или направление куда рыть, что бы сделать такой запрос только на mysql, без средств php, или как то от php цикла избавится

(Отредактировано автором: 10 Февраля, 2015 - 15:40:10)

 
 Top
KingStar
Отправлено: 10 Февраля, 2015 - 17:55:31
Post Id



Участник


Покинул форум
Сообщений всего: 1889
Дата рег-ции: Авг. 2011  
Откуда: Беларусь


Помог: 69 раз(а)




PHP:
скопировать код в буфер обмена
  1. $start = '2015.02.10';
  2. $end = '2015.03.15';
  3.        
  4. $query = '
  5.         SELECT
  6.                 e.id,
  7.                 e.name
  8.                
  9.         FROM
  10.                 event e
  11.                
  12.         INNER JOIN
  13.                 event_days_of_week d
  14.         ON
  15.                 d.event_id = e.id
  16.  
  17.         WHERE
  18.                 e.start <= '.$start.' AND
  19.                 e.end >= '.$end.' AND
  20.                 (
  21.                         Monday != 0 OR
  22.                         Tuesday != 0 OR
  23.                         Wednesday != 0 OR
  24.                         Thursday != 0 OR
  25.                         Friday != 0 OR
  26.                         Suturday != 0 OR
  27.                         Sunday != 0 OR
  28.                 )
  29.         ORDER BY
  30.                 Monday,
  31.                 Tuesday,
  32.                 Wednesday,
  33.                 Thursday,
  34.                 Friday,
  35.                 Suturday,
  36.                 Sunday
  37. ';
  38.  


-----
То что программа работает, не означает что она написана правильно!
 
 Top
exlant
Отправлено: 10 Февраля, 2015 - 19:46:22
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




это совсем не то, ваш запрос пропустит все события в которых хоть в одном дне будет стоять 0 Огорчение

неужели это такой уж трудный запрос???

наверное надо выбирать все события одним запросом со всеми днями, только по датам начала и конца отсеять, а остальное делать средствами пхп....

(Отредактировано автором: 10 Февраля, 2015 - 19:52:18)

 
 Top
exlant
Отправлено: 11 Февраля, 2015 - 08:21:15
Post Id



Посетитель


Покинул форум
Сообщений всего: 425
Дата рег-ции: Февр. 2015  


Помог: 14 раз(а)




я все таки это сделал Радость
PHP:
скопировать код в буфер обмена
  1.  
  2. $mysqli = new mysqli(parent::SERVER,parent::USER,parent::PASS,parent::DB);
  3.         //$mysqli = parent::$connect_db;
  4.         $mysqli->query("DROP PROCEDURE IF EXISTS get_events");
  5.        
  6.         $query = 'CREATE PROCEDURE get_events()  
  7.        BEGIN  
  8.        DECLARE i INT DEFAULT 0;
  9.         DECLARE week_day VARCHAR(10);
  10.                
  11.        WHILE i<28 DO
  12.            SET week_day = DAYNAME(ADDDATE(CURDATE(),i));
  13.            SET @query:=CONCAT("
  14.                SELECT e.id,e.name,e.text,e.time,e.importance FROM event e
  15.                INNER JOIN event_days_of_week d ON d.event_id=e.id
  16.                WHERE e.start <= ADDDATE(CURDATE(),",i,") AND e.end >= ADDDATE(CURDATE(),",i,")
  17.                AND d.",week_day," != 0;");
  18.            PREPARE query FROM @query;
  19.            EXECUTE query;
  20.            DEALLOCATE PREPARE query;
  21.            SET i = i + 1;
  22.        END WHILE;
  23.        END';
  24.        
  25.         $mysqli->query($query);
  26.                
  27.         $mysqli->multi_query('CALL get_events()');
  28.        
  29.         $a=0;
  30.         do {
  31.             if ($res = $mysqli->store_result()) {
  32.                
  33.                 $day_of_week = date('l',  mktime(0,0,0, date('m'),date('d')+$a, date('Y')));
  34.                 $date = date('Y-m-d',  mktime(0,0,0, date('m'),date('d')+$a, date('Y'))).'('.$day_of_week.')';
  35.                
  36.                 while($row = $res->fetch_assoc()){
  37.                     $data[$date][] = $row;
  38.                 }
  39.                 $res->free();
  40.                 $a++;
  41.                
  42.             } else {
  43.                 if ($mysqli->errno) {
  44.                     echo "Не удалось получить результат на клиенте: (" . $mysqli->errno . ") " . $mysqli->error;
  45.                 }
  46.             }
  47.         } while ($mysqli->more_results() && $mysqli->next_result());
  48.         var_dump($data);
  49.  


осталось только привести все это в нормальный вид))


теперь появился еще вопрос!
Может первый вариант предпочтительней???

(Отредактировано автором: 11 Февраля, 2015 - 08:30:53)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB