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
Форумы портала PHP.SU :: Версия для печати :: оптимизировать запрос
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » оптимизировать запрос

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

1. exlant - 10 Февраля, 2015 - 05:51:02 - перейти к сообщению
есть две таблицы
В таблице 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.  

можно ли как то это оптимизировать, что бы не делать столько запросов к базе?
2. KingStar - 10 Февраля, 2015 - 11:46:18 - перейти к сообщению
условие составить в цикле, а сам запрос вынести из цикла, дату через BETWEEN
3. exlant - 10 Февраля, 2015 - 13:44:37 - перейти к сообщению
KingStar пишет:
условие составить в цикле, а сам запрос вынести из цикла, дату через BETWEEN


а как составить это условие в цикле? если бы я знал как, я бы не спрашивал...
и по поводу BETWEEN, читал на каком то сайте что лучше через больше меньше, так быстрее выходит
4. KingStar - 10 Февраля, 2015 - 13:59:30 - перейти к сообщению
вообще не понимаю, зачем здесь цикл
у тебя количество дней от 0 до 28
дату выбираешь от текущей, до +28 и день недели != 0

то, что ты сейчас делаешь - это ищешь на каждый день 0123....28
а это равносильно что искать на весь промежуток 0-28
5. exlant - 10 Февраля, 2015 - 15:38:29 - перейти к сообщению
а мне вот и надо промежуток от 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 цикла избавится
6. KingStar - 10 Февраля, 2015 - 17:55:31 - перейти к сообщению
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.  
7. exlant - 10 Февраля, 2015 - 19:46:22 - перейти к сообщению
это совсем не то, ваш запрос пропустит все события в которых хоть в одном дне будет стоять 0 Огорчение

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

наверное надо выбирать все события одним запросом со всеми днями, только по датам начала и конца отсеять, а остальное делать средствами пхп....
8. exlant - 11 Февраля, 2015 - 08:21:15 - перейти к сообщению
я все таки это сделал Радость
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.  


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


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

 

Powered by ExBB FM 1.0 RC1