За последние 24 часа нас посетили 55435 программистов и 1795 роботов. Сейчас ищут 803 программиста ...

оптимизация запроса

Тема в разделе "MySQL", создана пользователем exlant, 11 фев 2015.

  1. exlant

    exlant Новичок

    С нами с:
    11 фев 2015
    Сообщения:
    5
    Симпатии:
    0
    есть две таблицы
    В таблице event хранятся события, и есть колонки id,name,start,end;
    в event_days_of_week есть id_event, Monday, Tuesday, Wednesday, Thursday, Friday, Suturday, Sunday

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

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

    решил задачу средствами php, закинув SELECT в цикл
    Код (Text):
    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);
    и одним запросом
    Код (Text):
    1.  
    2. $mysqli = new mysqli(parent::SERVER,parent::USER,parent::PASS,parent::DB);
    3.        
    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.              
    34.                 $date = date('Y-m-d(l)',  mktime(0,0,0, date('m'),date('d')+$a, date('Y')));
    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);
    какой из вариантов предпочтительней, и почему??
    или можно как то сделать по другому?
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    два раза за неделю не бывает чтоли?
     
  3. exlant

    exlant Новичок

    С нами с:
    11 фев 2015
    Сообщения:
    5
    Симпатии:
    0
    бывает! я наверно не правильно описал...
    у разных событий в поле День недели, разные числа по ним и надо сортировать
    например имеем строчки id = 1, name = event, start = 2015.02.10, end 2015.03.15, Monday = 1, Tuesday = 2, Wednesday = 2, Thursday = 2, Friday = 0, Suturday = 0, Sunday = 0, и строчку №2 id = 2, name = event_2, start = 2015.02.12, end 2015.04.15, Monday = 2, Tuesday = 3, Wednesday = 1, Thursday = 1, Friday = 1, Suturday = 1, Sunday = 1

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

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    тогда проще выбрать все по дате, а таблицу отрисовать в пхп уже проходясь по всему списку каждый день
     
  5. exlant

    exlant Новичок

    С нами с:
    11 фев 2015
    Сообщения:
    5
    Симпатии:
    0
    изначально так и думал сделать, но потом задался целью сделать все средствами mysql, в учебных целях)