За последние 24 часа нас посетил 52441 программист и 1767 роботов. Сейчас ищут 790 программистов ...

Сложный запрос на выборку

Тема в разделе "MySQL", создана пользователем Kocapb, 30 май 2010.

  1. Kocapb

    Kocapb Активный пользователь

    С нами с:
    10 июл 2008
    Сообщения:
    169
    Симпатии:
    0
    Добре время суток. Наткнулся на проблему которую не могу решить.
    Есть БД. В таблице поля date_start, date_end тип DATE, time_start, time_end тип TIME;
    В эту базу данных заносится дата врямя начала смены работы (date_start, time_start), и врямя конца смены работы (date_end, time_end).
    Смена может начаться в 23:00 и закончится в 8:00 следующего дня.
    Задача следующая: вывести статистику работы за неделю.
    сделал запрос:
    PHP:
    1.  
    2.   $res = mysql_query("SELECT *
    3.                                     FROM `stats`
    4.                                   WHERE `date_start` >= '".date_convert_to($date_from)."'
    5.                                       AND `date_end` <= '".date_convert_to($date_to)."'
    6.                                ORDER BY `date_start`,`date_end`
    7.                                 ");
    8.  
    9.  
    но столкнулся с проблемой следующего характера:
    [​IMG]
    [​IMG]
    29ого числа в 23:00 начинается смена другой недели. А в интервал попадает 29ое число смена с 8:00 до 16:00 и 17:00 до 22:00. Как сделать так чтобы это исключить?
    Как-то надо сделать следующее: С первой записи выборки и последней сделать фильтр по времени.
    Пытался реализовать, но фильтр действует на каждую запись в отдельности.
    PHP:
    1.  
    2.   $time_start = 23:00:00;
    3.   $res = mysql_query("SELECT *
    4.                                     FROM `stats`
    5.                                   WHERE `date_start` >= '".date_convert_to($date_from)."'
    6.                                       AND `date_end` <= '".date_convert_to($date_to)."'
    7.                                       AND `time_start` >='".$time_start."'
    8.                                ORDER BY `date_start`,`date_end`
    9.                                ");
    10.  
    Моя идея может не работать, готов выслушать любые советы. Вплоть на то в какую сторону копать. Заранее спасибо
     
  2. Einbaukueche

    Einbaukueche Активный пользователь

    С нами с:
    14 апр 2010
    Сообщения:
    34
    Симпатии:
    0
    Адрес:
    Там, где много гор и пива.
    Может быть, неправильно понял, что вам надо, но почему бы не просто так?

    Если я правильно вас понял, то принадлежность одной строки к какой-то рабочей неделе завязана только на начале рабочего дня. То есть date_end вам в выборке не нужен, или нет?

    Код (Text):
    1.  
    2. mysql> SELECT *
    3.     -> FROM stats
    4.     -> ORDER BY date_start ASC;
    5. +---------------------+---------------------+
    6. | date_start          | date_end            |
    7. +---------------------+---------------------+
    8. | 2010-05-25 23:00:00 | 2010-05-26 09:00:00 |
    9. | 2010-05-26 08:00:00 | 2010-05-26 16:00:00 |
    10. | 2010-05-26 13:00:00 | 2010-05-26 23:30:00 |
    11. | 2010-05-26 23:00:00 | 2010-05-27 09:00:00 |
    12. | 2010-05-27 08:00:00 | 2010-05-27 16:00:00 |
    13. | 2010-05-27 13:00:00 | 2010-05-27 23:30:00 |
    14. | 2010-05-27 23:00:00 | 2010-05-28 09:00:00 |
    15. | 2010-05-28 08:00:00 | 2010-05-28 16:00:00 |
    16. | 2010-05-28 13:00:00 | 2010-05-28 23:30:00 |
    17. | 2010-05-28 23:00:00 | 2010-05-29 09:00:00 |
    18. | 2010-05-29 08:00:00 | 2010-05-29 16:00:00 |
    19. | 2010-05-29 18:00:00 | 2010-05-30 08:00:00 |
    20. | 2010-05-29 23:00:00 | 2010-05-30 09:00:00 |
    21. | 2010-05-30 08:00:00 | 2010-05-30 16:00:00 |
    22. +---------------------+---------------------+
    23. 14 rows in set (0.00 sec)
    24.  
    25.  
    26. mysql> SET @this_week_start = '2010-05-26 23:00:00';
    27. Query OK, 0 rows affected (0.00 sec)
    28.  
    29. mysql> SET @next_week_start = '2010-05-29 23:00:00';
    30. Query OK, 0 rows affected (0.00 sec)
    31.  
    32. mysql> SELECT *
    33.     -> FROM stats
    34.     -> WHERE date_start >= @this_week_start
    35.     -> AND date_start < @next_week_start
    36.     -> ORDER by date_start ASC;
    37. +---------------------+---------------------+
    38. | date_start          | date_end            |
    39. +---------------------+---------------------+
    40. | 2010-05-26 23:00:00 | 2010-05-27 09:00:00 |
    41. | 2010-05-27 08:00:00 | 2010-05-27 16:00:00 |
    42. | 2010-05-27 13:00:00 | 2010-05-27 23:30:00 |
    43. | 2010-05-27 23:00:00 | 2010-05-28 09:00:00 |
    44. | 2010-05-28 08:00:00 | 2010-05-28 16:00:00 |
    45. | 2010-05-28 13:00:00 | 2010-05-28 23:30:00 |
    46. | 2010-05-28 23:00:00 | 2010-05-29 09:00:00 |
    47. | 2010-05-29 08:00:00 | 2010-05-29 16:00:00 |
    48. | 2010-05-29 18:00:00 | 2010-05-30 08:00:00 |
    49. +---------------------+---------------------+
    50. 9 rows in set (0.00 sec)
     
  3. Kocapb

    Kocapb Активный пользователь

    С нами с:
    10 июл 2008
    Сообщения:
    169
    Симпатии:
    0
    Всё верно, но новая неделя начинается, в приведённом в моём примере, с 29 ого числа в 23:00.
    А в выборку следующей недели (с 2010-05-29 по 2010-06-05) попадает смена 29 ого числа с 8:00 до 16:00
    и с 13:00 до 20:30.
    [​IMG]
    необходимо сделать запрос в котором бы следующая неделя начиналась с 2010-05-29 23:00:00.
    А вот как это сделать я ума не приложу.
    Вчера ночью пришла идея сделать несколько запросов и совместить их, но пока не реализовал =(
     
  4. Einbaukueche

    Einbaukueche Активный пользователь

    С нами с:
    14 апр 2010
    Сообщения:
    34
    Симпатии:
    0
    Адрес:
    Там, где много гор и пива.
    Ну. И? Не понимаю, в чём проблема.

    Это только вопрос правильного определения начала той недели, которая интересует и той после неё.

    Код (Text):
    1.  
    2. mysql> SELECT *
    3.     -> FROM stats
    4.     -> ORDER BY date_start ASC;
    5. +---------------------+---------------------+
    6. | date_start          | date_end            |
    7. +---------------------+---------------------+
    8. | 2010-05-25 23:00:00 | 2010-05-26 09:00:00 |
    9. | 2010-05-26 08:00:00 | 2010-05-26 16:00:00 |
    10. | 2010-05-26 13:00:00 | 2010-05-26 23:30:00 |
    11. | 2010-05-26 23:00:00 | 2010-05-27 09:00:00 |
    12. | 2010-05-27 08:00:00 | 2010-05-27 16:00:00 |
    13. | 2010-05-27 13:00:00 | 2010-05-27 23:30:00 |
    14. | 2010-05-27 23:00:00 | 2010-05-28 09:00:00 |
    15. | 2010-05-28 08:00:00 | 2010-05-28 16:00:00 |
    16. | 2010-05-28 13:00:00 | 2010-05-28 23:30:00 |
    17. | 2010-05-28 23:00:00 | 2010-05-29 09:00:00 |
    18. | 2010-05-29 08:00:00 | 2010-05-29 16:00:00 |
    19. | 2010-05-29 18:00:00 | 2010-05-30 08:00:00 |
    20. | 2010-05-29 23:00:00 | 2010-05-30 09:00:00 |
    21. | 2010-05-30 08:00:00 | 2010-05-30 16:00:00 |
    22. +---------------------+---------------------+
    23. 14 rows in set (0.00 sec)
    24.  
    25. mysql> SET @this_week_start = '2010-05-29 23:00:00';
    26. Query OK, 0 rows affected (0.00 sec)
    27.  
    28. mysql> SET @next_week_start = '2010-06-05 23:00:00';
    29. Query OK, 0 rows affected (0.00 sec)
    30.  
    31. mysql> SELECT *
    32.     -> FROM stats
    33.     -> WHERE date_start >= @this_week_start
    34.     -> AND date_start < @next_week_start
    35.     -> ORDER BY date_start ASC;
    36. +---------------------+---------------------+
    37. | date_start          | date_end            |
    38. +---------------------+---------------------+
    39. | 2010-05-29 23:00:00 | 2010-05-30 09:00:00 |
    40. | 2010-05-30 08:00:00 | 2010-05-30 16:00:00 |
    41. +---------------------+---------------------+
    42. 2 rows in set (0.06 sec)
     
  5. Kocapb

    Kocapb Активный пользователь

    С нами с:
    10 июл 2008
    Сообщения:
    169
    Симпатии:
    0
    я идею понял, но время начала смены и конца у меня храниться в разных ячейках. Поэтому наверное и не работает как у тебя.
    time_start, time_end.
    структура таблицы:
    [​IMG]
    просто я потом для наглядности их совмещаю:
    PHP:
    1.  
    2. '<td nowrap>'.$row['date_start'].' '.$row['time_start'].'</td>'.
    3. '<td nowrap>'.$row['date_end'].' '.$row['time_end'].'</td>'.
    4.  
    все записи:
    [​IMG]
    если пишу запрос сортировкой для времени, то от выкидывает все остальные смены которые начались не 23:00:00.
    PHP:
    1.  
    2. $date_start = '2010-05-29';
    3. $date_end  = '2010-06-05';
    4. $time_star = '23:00:00';
    5.  
    6. $res = mysql_query("SELECT *
    7.                                    FROM `stats`
    8.                                   WHERE `date_start` >= '".$date_start."'
    9.                                     AND `date_start` < '".date_end."'
    10.                                     AND `time_start` >= '".$time_start."'  
    11.  
    12. ORDER BY `date_start`,`date_end`
    13.  
    [​IMG]
    Так не хочется структуру переделывать. Попробую с интервалами разобраться.
    Есть еще одна идея:
    сделать выборку по одной дате (начала недели), с критерием смены (23:00:00).
    потом, выборку до конца недели не включая последний день, и затем
    выборку последнего дня где смена заканчивается в 23:00.
     
  6. Kocapb

    Kocapb Активный пользователь

    С нами с:
    10 июл 2008
    Сообщения:
    169
    Симпатии:
    0
    или может объединение полей сделать, такое возможно?
     
  7. Kocapb

    Kocapb Активный пользователь

    С нами с:
    10 июл 2008
    Сообщения:
    169
    Симпатии:
    0
    нашел решение
    [sql]
    SELECT * FROM `stats`
    WHERE concat_ws(" ",`date_start`, `time_start`) >= "2010-05-29 23:00:00"
    [/sql]