За последние 24 часа нас посетили 30373 программиста и 1753 робота. Сейчас ищут 842 программиста ...

Как сделать выборку из Mysql по временным интервалам от, до

Тема в разделе "PHP для новичков", создана пользователем ekip, 13 янв 2010.

  1. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Ребята помогите бьюсь 2-е сутки. Столкнулся с проблемой вывода данных из таблицы Mysql по временным интервалам "от" и "до".
    Данные указываются в полях формы и отправляются в обработчик.
    Т.е. нужно выводить данные в интервалах между разными датами указанными в полях при заполнении формы
    PHP:
    1. <?php
    2. // входящие данные преобразуются из d.m.y в timestamp формат для сравнения
    3. $date = $_POST['min']; // входящие данные "от"
    4. if (ereg ("([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})", $date, $min)) $mininum = "$min[3].$min[2].$min[1] 00:00:00"; // входящие данные "от" в timestamp формате например 2010.01.01 00:00:00
    5.  
    6. $dates = $_POST['max']; // входящие данные "до"
    7. if (ereg ("([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})", $dates, $max)) $maximum = "$max[3].$max[2].$max[1] 00:00:00"; // входящие данные "до" в timestamp формате например 2010.01.11 00:00:00
    8.  
    9. require 'connect.php';
    10. mysql_query('SET NAMES `utf8`');
    11. $result = mysql_query("SELECT * FROM zayavki WHERE ...");
    12. while($row = mysql_fetch_array($result))
    13. {
    14. echo '';
    15. }
    16. ?>
    Заранее благодарен за помощь
     
  2. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    ekip
    А не судьба хранить время и дату в базе в формате unix timestamp?
    Тогда можно сделать так:

    [sql]SELECT title FROM articles WHERE (date > 1 AND date < 111211)[/sql]

    И, при получении из формы, использовать функцию mktime()
     
  3. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    PHP:
    1.     <?php
    2.  
    3.     if(!empty($_POST['from']))$W[]='DATE(`dt`)>=DATE(\''.date('Y-m-d', strtotime($_POST['from'])).'\')';
    4.     if(!empty($_POST['to']))$W[]='DATE(`dt`)<=DATE(\''.date('Y-m-d', strtotime($_POST['to'])).'\')';
    5.  
    6.     $q=mysql_query('SELECT * FROM `#table#`'.(!empty($W)?' WHERE '.implode(' AND ',$W):''));
    7.  
    8.  
     
  4. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Так можно делать и для DATETIME формата

    Но в каком формате у ТС в базе одному богу ивзвестно.
     
  5. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    Simpliest
    ВНЕЗАПНО, страшно даже подумать.
     
  6. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Действительно если давать такие запросы данные нужно хранить unix формате.
    Спасибо admyx!

    Что получилось:

    PHP:
    1. <?php
    2. $datemin = $_POST['min']; // входящие данные "от"
    3. $datemax = $_POST['max']; // входящие данные "до"
    4.  
    5.  
    6. $datemin_time  = explode(".",$datemin); // разбивка значения на (.)
    7. $postdata_min = mktime(0,0,0,$datemin_time[1],$datemin_time[0],$datemin_time[2]); // преобразуем в unix
    8.  
    9.  
    10. $datemax_time  = explode(".",$datemax); // разбивка значения на (.)
    11. $postdata_max = mktime(0,0,0,$datemax_time[1],$datemax_time[0],$datemax_time[2]); // преобразуем в unix
    12.  
    13.  
    14. require 'connect.php';
    15. mysql_query('SET NAMES `utf8`');
    16. $result = mysql_query("SELECT * FROM zayavki WHERE (data > ".$postdata_min." AND data < ".$postdata_max.")"); // создали запрос
    17. while($row = mysql_fetch_array($result))
    18. {
    19. echo ''.$row['id'].''; // вывели
    20. }
    21. ?>
     
  7. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    ekip
    Рад, что вам помогло.
    А, если не секрет, в каком формате раньше дата хранилась в базе?
     
  8. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    ГГГГ-ММ-ДД ЧЧ:ММ:СС тип поля timestamp
     
  9. admyx

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

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    Мнятна)) Так и думал)
    unix timestamp лучше)
     
  10. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Еще возник вопрос с интервалами и датами, тот же самый код описанный выше:
    PHP:
    1. <?php
    2. $datemin = $_POST['min']; // входящие данные "от"
    3. $datemax = $_POST['max']; // входящие данные "до"
    4. $datemin_time  = explode(".",$datemin); // разбивка значения на (.)
    5. $postdata_min = mktime(0,0,0,$datemin_time[1],$datemin_time[0],$datemin_time[2]); // преобразуем в unix
    6. $datemax_time  = explode(".",$datemax); // разбивка значения на (.)
    7. $postdata_max = mktime(0,0,0,$datemax_time[1],$datemax_time[0],$datemax_time[2]); // преобразуем в unix
    8. function unix_time_convert ($timestamp)
    9. {
    10. $date = date ("d.m.Y" , $timestamp);
    11. return $date;
    12. }
    13. require 'connect.php';
    14. $query = "SELECT * FROM zayavki WHERE  izdanie = 1 AND(data > ".$postdata_min." AND data < ".$postdata_max.")
    15. ORDER BY data";
    16. $result = mysql_query($query);
    17. WHILE ($row = mysql_fetch_array($result)) {
    18. echo '';
    19. $time = $row['data'];
    20. $date = unix_time_convert($time);
    21. echo ''.$date.'';
    22. echo' г.; '.$row['summa'].'; <br>';
    23. }
    24. ?>
    При выполнении выводит даты по выбранному интервалу и данные с поля оплата (цикл):

    31.12.2009 г.; 12900;
    31.12.2009 г.; 12900;
    31.12.2009 г.; 12900;
    01.01.2010 г.; 4300;
    06.01.2010 г.; 5600;
    06.01.2010 г.; 5600;
    10.01.2010 г.; 23900;
    10.01.2010 г.; 23900;

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

    31.12.2009 г.; 38700;
    01.01.2010 г.; 4300;
    06.01.2010 г.; 11200;
    10.01.2010 г.; 47800;

    Как можно победить?
     
  11. 440Hz

    440Hz Старожил
    Команда форума Модератор

    С нами с:
    21 дек 2012
    Сообщения:
    8.003
    Симпатии:
    1
    Адрес:
    Оттуда
    GROUP BY и SUM()
     
  12. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Вот так:
    PHP:
    1. <?php
    2. $datemin = $_GET['min']; // входящие данные "от"
    3. $datemax = $_GET['max']; // входящие данные "до"
    4. $datemin_time  = explode(".",$datemin); // разбивка значения на (.)
    5. $postdata_min = mktime(0,0,0,$datemin_time[1],$datemin_time[0],$datemin_time[2]); // преобразуем в unix
    6. $datemax_time  = explode(".",$datemax); // разбивка значения на (.)
    7. $postdata_max = mktime(0,0,0,$datemax_time[1],$datemax_time[0],$datemax_time[2]); // преобразуем в unix
    8. function unix_time_convert ($timestamp)
    9. {
    10. $date = date ("d.m.Y" , $timestamp);
    11. return $date;
    12. }
    13. require 'connect.php';
    14. $query = "SELECT  data, SUM(summa) FROM zayavki WHERE  izdanie = 1 AND(data > ".$postdata_min." AND data < ".$postdata_max.")
    15. GROUP BY data " ;
    16. $result = mysql_query($query);
    17. WHILE ($row = mysql_fetch_array($result)) {
    18. echo '';
    19. $time = $row['data'];
    20. $date = unix_time_convert($time);
    21. echo ''.$date.'';
    22. echo' г.; '.$row['SUM(summa)'].'; <br>';
    23. }
    24. ?>
    440Hz спасибо!
     
  13. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    PHP:
    1. <?php
    2. $datemin = $_POST['min']; // входящие данные "от"
    3. $datemax = $_POST['max']; // входящие данные "до"
    4. $datemin_time  = explode(".",$datemin); // разбивка значения на (.)
    5. $postdata_min = mktime(0,0,0,$datemin_time[1],$datemin_time[0],$datemin_time[2]); // преобразуем в unix
    6. $datemax_time  = explode(".",$datemax); // разбивка значения на (.)
    7. $postdata_max = mktime(0,0,0,$datemax_time[1],$datemax_time[0],$datemax_time[2]); // преобразуем в unix
    8. function unix_time_convert ($timestamp)
    9. {
    10. $date = date ("d.m.Y" , $timestamp);
    11. return $date;
    12. }
    13. require 'connect.php';
    14. $query = "SELECT  data, SUM(summa) FROM zayavki WHERE  izdanie = 1 AND(data > ".$postdata_min." AND data < ".$postdata_max.")
    15. GROUP BY data " ;
    16. $result = mysql_query($query);
    17. $file="temp_1.csv";
    18. $fp=fopen("$file", 'w+');
    19. WHILE ($row = mysql_fetch_array($result)) {
    20. echo '';
    21. $time = $row['data'];
    22. $summa = $row['SUM(summa)'];
    23. $date = unix_time_convert($time);
    24. $inf = ''.$date.' г.; '.$summa.';';
    25. fwrite($fp, "$inf \n");
    26. }
    27. ?>
    28.  
    Я получил и суммировал все заявки по каждому числу в запросе поставил условие izdanie = 1
    Т.е. отобрал только те которые относятся к 1 изданию, в поле izdanie существует значение izdanie = 2
    В вышеприведенном коде я записываю полученные данные в файл temp_1.csv
    в виде:

    31.12.2009 г.; 38700;
    01.01.2010 г.; 4300;
    06.01.2010 г.; 11200;
    10.01.2010 г.; 47800;

    далее подключаю файл temp_1.csv к amCharts и получаю график.
    На графике должны отображаться 2 показателя, отображается только 1 т.е. izdanie = 1

    Т.е. нужно запрос скорректировать так что бы
    можно было записать данные в виде:

    31.12.2009 г.; 38700; 1233;
    01.01.2010 г.; 4300; 4300;
    06.01.2010 г.; 11200; 32000;
    10.01.2010 г.; 47800; 1254;

    Можно ли такое реализовать?
     
  14. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Можно, но несколько неудобно.

    Несколько проще получить такое. Надо просто сделать группировку по двум полям - дате и изданию
    31.12.2009 г.; 38700;
    31.12.2009 г.; 1233;
    01.01.2010 г.; 4300;
    01.01.2010 г.; 4300;
    06.01.2010 г.; 11200;
    06.01.2010 г.; 32000;
    10.01.2010 г.; 47800;
    10.01.2010 г.; 1254;

    или нужен все же вариант?
    31.12.2009 г.; 38700; 1233;
     
  15. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Simpliest идея конечно хорошая но не совсем подходит,
    amCharts разбивает значения на (;)

    дата 1 график 2 график
    ----------------|-----------|--------
    31.12.2009 г.; 38700; 1233;

    в предложенном варианте в графике просто дублируются даты с разными значениями

    поэтому нужен вариант
    31.12.2009 г.; 38700; 1233;
     
  16. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    А когда потребуется 3й? тоже так же рядом?

    Я предлагаю тебе сделать выборку как я сказал. А собрать строку уже в PHP

    на SQL это весьма громоздко. У тебя будет несколько JOIN на подзапросы.
     
  17. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    PHP:
    1.  
    2. <?php
    3. WHILE ($row = mysql_fetch_array($result)) {
    4. echo '';
    5. $izdanie = $row['izdanie'];
    6. $time = $row['data'];
    7. $summa = $row['SUM(summa)'];
    8. $date = unix_time_convert($time);
    9. $inf_one = ''.$date.' г.; '.$summa.';';
    10. $inf_two = ''.$summa.';';
    11. if ($izdanie == 2)
    12. echo $inf_two;
    13. else
    14. echo $inf_one;
    15. fwrite($fp, "$inf \n"); // записывали $inf
    16. }
    17. ?>
    Ну собственно получилось вывести как положено, но вот записать теперь как? Если я до этого записывал переменную $inf то теперь нужно записать условие. :cry:
     
  18. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    PHP:
    1. <?php
    2. $lines = array();
    3.  
    4. while (false !== ($row = mysql_fetch_array($result))) {
    5.     if (isset($lines[$row['data'])) {
    6.         $lines[$row['data']] .= ';' . $row['SUM(summa)'];
    7.     } else {
    8.         $lines[$row['data']] = $row['data'] . ';' . $row['SUM(summa)'];
    9.     }
    10. }
    11. $toFile = implode("\n",$lines);
    12. file_put_contents('my.csv', $toFile);
     
  19. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    offtopic:: Simpliest - впервые вижу стиль похожий на мой :)
     
  20. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    А что в нем похожего-то? :) в 10 строчках...
     
  21. nimistar

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

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    Вот это:
    PHP:
    1. <?
    2.   while (false !== ($row = mysql_fetch_array($result))) {
    3.       if (isset($lines[$row['data'])) {
    4. ...
    5.  
    по правилам вроде должно быть :
    PHP:
    1. <?
    2.   while (($row = mysql_fetch_array($result))!==false)
    3.   {
    4.       if (isset($lines[$row['data']))
    5.      {
    6. ....
    7.  
    а вообще кто во что горазд, но { "на" строчке , а не "под" - мало кто использует
     
  22. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    Никак я не осилю, новый косяк появился от группировки
    PHP:
    1. <?php
    2. $datemin = $_GET['min']; // входящие данные "от"
    3. $datemax = $_GET['max']; // входящие данные "до"
    4. $datemin_time  = explode(".",$datemin); // разбивка значения на (.)
    5. $postdata_min = mktime(0,0,0,$datemin_time[1],$datemin_time[0],$datemin_time[2]); // преобразуем в unix
    6. $datemax_time  = explode(".",$datemax); // разбивка значения на (.)
    7. $postdata_max = mktime(0,0,0,$datemax_time[1],$datemax_time[0],$datemax_time[2]); // преобразуем в unix
    8. function unix_time_convert ($timestamp)
    9. {
    10. $date = date ("d.m.Y" , $timestamp);
    11. return $date;
    12. }
    13. require 'connect.php';
    14. $query = "SELECT  data,izdanie, SUM(summa) FROM zayavki WHERE (data > ".$postdata_min." AND data < ".$postdata_max.")
    15. GROUP BY data,izdanie " ;
    16. $result = mysql_query($query);
    17. $file="temp_1.csv";
    18. $toFile = fopen("$file", 'w+');
    19. $lines = array();  
    20. while (false !== ($row = mysql_fetch_array($result))) {
    21. $summa = $row['SUM(summa)'];
    22. $time = $row['data'];
    23. $date = unix_time_convert($time);
    24. if (isset($lines[$date])) {
    25. $lines[$date] .= '' . $summa  . ';';
    26. } else {
    27. $lines[$date] = $date . ' г.; ' . $summa  . '; ';
    28. }
    29. }
    30. $toFile = implode("\n",$lines);
    31. file_put_contents('temp_1.csv', $toFile);
    32. ?>
    В файл temp_1.csv пишет:
    31.12.2009 г.; 22800;
    02.01.2010 г.; 41100;
    03.01.2010 г.; 19900; 23900;12600;23900;
    05.01.2010 г.; 11300; 5600;
    06.01.2010 г.; 22800;
    07.01.2010 г.; 28200; 12900;
    08.01.2010 г.; 30950;
    09.01.2010 г.; 5600;
    10.01.2010 г.; 7000;



    03.01.2010 г.; 19900; 23900;12600;23900; то что в конце 2 суммы: 12600;23900; это тоже 03.01.2010 г. а возникло это из за того что стоит GROUP BY data, так как даты записаны в формате unix timestamp группирует запрос только строго равные числа, например 1262470800 и 1262450000 это все 03.01.2010 г. а группировка на эти числа(даты) не работают, поэтому он выплевывает нам такое, еже не знаю что делать даже...

    :cry:
     
  23. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Как нам рассказывал один человек открытие блока на следующей строчке пошло с древних времен от С программистов, которым платили за количество созданных строчек кода. Открытие блока на той же строчке более соответствует стилю Java программирования.
     
  24. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Честно? В большинстве случаев это делает IDE, мне такое не мешает, вот и все :) Ну и пустая висячая строчка с одной скобкой иногда раздражает - когда кода немного.

    ekip
    Ну так и группируй не по самой дате, а по DATEFORMAT('yyyy.mm.dd', data) (синтаксис правильный посмотришь на dev.mysql.com)
    и в поле это же выводи, иначе у тебя строки не будут собираться правильно.
     
  25. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    И такой момент
    почитай мануал - что кто возращает и какие параметры принимает
    http://php.net/fopen
    http://php.net/file_put_contents