Как правильно сделать статистику...???

Little Bear

Новичок
Как правильно сделать статистику...???

Вот такая вот проблемка...

Есть две таблицы: районы и поездки

areas
id_area | area_name

trips
id_trip | driver_name | start_area | start_street | stop_area | stop_street | client_tel_number | kilometrage | price | trip_date

Нужно сделать так, чтобы после выбора интервала дат(от такой-то даты"start_date" до такой-то"stop_date") выводилась статистика в виде таблицы, которая выглядит вот так:

Район________Понедельник_Вторник_Среда__Четверг__Пятница_Суббота_Воскресенье
назв. района 1____5__________ 5______3_______3_______8________2__________7___
назв. района 2____3 __________3______6_______3_______5________4__________4___
назв. района 3
назв. района 4

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

Понимаю, что сначала нужно выбрать все поездки, у которых trip_date входит в заданный промежуток (start_date < trip_date < stop_date)

Потом из них уже начать выбирать поездки по районам и по дням... Но как правильно это сделать??? День недели можно узнать с помощью WEEKDAY....

У меня просто не получается собрать все в кучу... Помогите пожалуйста...
Всем заранее огромное спасибо!
 

Gas

может по одной?
схематично так:
... COUNT(trips.id_trip) ...FROM areas LEFT JOIN trips ... WHERE .... GROUP BY id_area, WEEKDAY(trip_date)
 

Little Bear

Новичок
не понял... поясни, пожалуйста...
Как там все подсчитываться будет?
 

findnext

Новичок
a это дословно:
...подсчитать(количество идентификаторов таблицы trips) ...ИЗ таблицы areas + присоединить слева таблицу trips ... где ... группировка по идентификаторам area, по дням недели
 

Beavis

Banned
Little Bear
ты хочешь чтоб за тебя сделали всю работу и написали запрос? или нет, напиши, что получилось у тебя, и что именно не работает, а мы тебе поможем
 

Little Bear

Новичок
Ни в коем случае! Я просто новичек еще в php...
Сегодня-завтра подумаю еще, все попробую, если ничего не получится, то напишу...

Не работал еще с COUNT , LEFT JOIN и GROUP BY... )))
Постараюсь понять, как они работают.. Если получится все, то выложу завтра код, нет - вопрос )))

До завтра всем! И еще раз спасибо за хлопоты!

-~{}~ 23.12.08 09:37:

PHP:
<?php
include_once("mysql.php");

$start_date = $_POST['start_year'].'-'.$_POST['start_month'].'-'.$_POST['start_day'];
$stop_date = $_POST['stop_year'].'-'.$_POST['stop_month'].'-'.$_POST['stop_day'];

echo "$start_date";
echo "$stop_date";


$result=mysql_db_query("TAXI", "select * from areas");
$i=0;

echo "<table border=1>";
echo "<tr>";
echo "<td>Район</td>";
echo "<td>Понедельник</td>";
echo "<td>Вторник</td>";
echo "<td>Среда</td>";
echo "<td>Четверг</td>";
echo "<td>Пятница</td>";
echo "<td>Суббота</td>";
echo "<td>Воскресенье</td>";
echo "</tr>";
while ($i<mysql_num_rows($result))
{
echo "<tr>";
echo "<td>".mysql_result($result, $i, "area_name")."</td>";
$result2=mysql_db_query("TAXI", "SELECT COUNT(*) FROM trips t WHERE t.start_area='".mysql_result($result, $i, "area_name")."'");

//AND trip_date BETWEEN ($start_date AND $stop_date) 
//echo "SELECT COUNT(*) FROM trips t WHERE t.start_area='".mysql_result($result, $i, "area_name")."'";
//echo "<td>".mysql_result($result2, $i, "COUNT(*)")."</td>";
	for ($j=0; $j<7; $j++)
	{
		echo "<td>".@mysql_result($result2, 0, "COUNT(*)")."</td>";
	}
$i++;
}
echo "</tr>";
echo "</table>";


?>
Он выводит таблицу по районам и в каждом дне вносит данные сколько было совершено поездок.. 5-5-5-5-5-5-5...

Как теперь можно привязать еще WEEKDAY?
И как правильно вставить проверку условия на то, что дата поездки входит в заданный промежуток дат?...

Заранее спасибо за ответы! А я пошел думать пока сам... Может еще что получиться... )))
 

Splurov

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

x-yuri

Новичок
во-первых в trips нужно добавить id_area, чтобы привязать к району поездки, которые в нем проводятся ну и сами данные связать надо

во-вторых запрос
Код:
SELECT id_area, WEEKDAY(trip_date), COUNT(trips.id_trip) 
FROM areas LEFT JOIN trips USING(id_area) 
WHERE (? <= trip_date)  && (trip_date <= ?)
GROUP BY id_area, WEEKDAY(trip_date)
первый ? - начало периода, второй - конец
LEFT JOIN - чтобы получить записи о районах, в которых не проводтся поездки для заданного периода

Я не совсем понимаю, как он работает и куда его вставлять...
для начала можно вставить в phpmyadmin, а если не поможет...
что именно ты не понимаешь? а то я "совсем" не понимаю, что ты не понимаешь
 

Денч

Новичок
Автор оригинала: Little Bear
Я не совсем понимаю, как он работает и куда его вставлять...
Little Bear
SQL-запрос, который дал Gas, нужно впихнуть в $sql, и
PHP:
$res = mysql_query($sql).
Потом с помощью
PHP:
while($data = mysql_fetch_assoc($res))  
{      
       ?>pre<?      
       var_dump($data);      
       ?></pre><?  
}
посмотреть, что получилось. Там сразу увидишь свои данные из таблиц БД, и немедлено сообразишь, как использовать данные в $data, чтобы построить необходимую HTML-таблицу
 

Little Bear

Новичок
Я всетаки пошел своим путем )))
Я смог извлечь все нужные мне даннные... Но они немнго неправильно выводятся..
Если нет поездки в определенный день, в определенном районе, то он сдвигает значения на один столбец левее.

Поясню... Если из района Топкинский совершалось 3 поездки в понедельник, одна в среду и одна в пятницу, то он вносит данные так

П В С Ч П С В
3 1 1

Как можно сделать, чтобы он вносил в поля, где не было поездок 0???

А вот мой скрипт
PHP:
<?php
include_once("mysql.php");

$start_date = $_POST['start_year'].'-'.$_POST['start_month'].'-'.$_POST['start_day'];
$stop_date = $_POST['stop_year'].'-'.$_POST['stop_month'].'-'.$_POST['stop_day'];

echo "$start_date";
echo "$stop_date";


$query = "select * from areas";
$db = mysql_db_query("taxi",$query);

echo "<table border=1>";
echo "<tr>";
echo "<td>Район</td>";
echo "<td>Понедельник</td>";
echo "<td>Вторник</td>";
echo "<td>Среда</td>";
echo "<td>Четверг</td>";
echo "<td>Пятница</td>";
echo "<td>Суббота</td>";
echo "<td>Воскресенье</td>";
echo "</tr>";

while ($i = mysql_fetch_array($db))
{
echo "<tr>";
echo "<td>".$i[area_name]."</td>";
$query2="SELECT COUNT(*), WEEKDAY(trip_date) FROM trips t WHERE t.start_area='".$i[area_name]. "' AND t.trip_date >= '$start_date' AND t.trip_date <= '$stop_date' GROUP BY WEEKDAY(trip_date)";
$db2 = mysql_db_query("taxi",$query2);
	$j = 0;
	while ($k = mysql_fetch_array($db2))
	{
		echo "<td>".$k['COUNT(*)']."</td>";	
	}
	

}
echo "</tr>";
echo "</table>";
?>
Надеюсь это мой последний вопрос касающийся этой темы )))
 

x-yuri

Новичок
Я все-таки пошел своим путем )))
тебе не зря советуют другой путь, лучше разберись в нем

не связывай таблицы с помощью строковых полей: areas.area_name <-> trips.start_area, используй для этого числовые ключи - areas.id_area <-> trips.start_area
т.е. второй запрос должен быть
Код:
$query2="SELECT COUNT(*), WEEKDAY(trip_date) 
FROM trips t 
WHERE t.start_area='".$i[id_area]. "' AND 
    t.trip_date >= '$start_date' AND 
    t.trip_date <= '$stop_date' 
GROUP BY WEEKDAY(trip_date)";
и в trips.start_area должны быть значения ключа из таблицы areas, аналогично trips.stop_area

по поводу связывания двух таблиц с помощью строковых полей: это медленно и ты дублируешь информацию - у тебя названия районов - в обоих таблицах. Чтобы изменить одно название тебе надо будет изменить одну запись в таблице areas и соответствующие записи в таблице trips, в моем варианте нужно изменить только одну запись в таблице areas

Если каждому району соответствует только одна улица, то ее лучше тоже вынести в таблицу areas

PHP:
...

$area_info = get_area_info( $area ); // у тебя $area названо $i
foreach( $area_info as $count ) {
    echo "<td>".$count."</td>";    
}

...

function get_area_info( $a ) {
    $query2="SELECT COUNT(*) trip_count, WEEKDAY(trip_date) week_day 
        FROM trips t 
        WHERE t.start_area='".$a[id_area]. "' AND 
            t.trip_date >= '$start_date' AND 
            t.trip_date <= '$stop_date' 
        GROUP BY WEEKDAY(trip_date)"; 
    $db2 = mysql_db_query("taxi",$query2);
    $k = mysql_fetch_assoc($db2);
    $r = array();
    for( $i=0; $i<7; $i++ ) {
        if( $k['week_day'] == $i ) {
            $r[] = $k['trip_count'];
            $k = mysql_fetch_assoc($db2);
        } else {
            $r[] = '';
        }
        return $r;
    }
}
 

Gas

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

Little Bear

Новичок
Привет, x-yuri !
Что именно нужно изменить в таблице areas?
И правильно ли я тебя понял, что нужно сделать связи в самой базе? То есть поля start_area и stop_area будут содержать значения id_area?
 

x-yuri

Новичок
Что именно нужно изменить в таблице areas?
как минимум start_area, stop_area - не хранить в них названия районов, а хранить id районов
т.е. если у района "район 3" id_area = 5, то у всех поездок начинающихся в этом районе start_area должно равняться 5, то же самое касается stop_area

-~{}~ 24.12.08 18:57:

это было по поводу trips :-[

-~{}~ 24.12.08 19:15:

еще можно создать список водителей, улиц, районов

drivers
id_driver | name

areas
id_area | name

streets
id_street | name | id_area

тогда

trips
id_trip | id_driver | id_start_street | id_stop_street | client_tel_number | kilometrage | price | trip_date

первый запрос
Код:
    SELECT COUNT(*) trip_count, WEEKDAY(trip_date) week_day  
        FROM trips t
            JOIN streets s ON t.id_start_street = s.id_street
            JOIN areas a ON s.id_area = a.id_area
        WHERE (a.id_area='".$a[id_area]. "') &&  
            (t.trip_date >= '$start_date') &&  
            (t.trip_date <= '$stop_date')  
        GROUP BY WEEKDAY(trip_date)
-~{}~ 24.12.08 19:19:

или в один запрос
Код:
SELECT a.id_area, COUNT(*) trip_count, WEEKDAY(trip_date) week_day  
        FROM trips t
            JOIN streets s ON t.id_start_street = s.id_street
            JOIN areas a ON s.id_area = a.id_area
        WHERE (t.trip_date >= '$start_date') &&  
            (t.trip_date <= '$stop_date')  
        GROUP BY a.id_area, WEEKDAY(trip_date)
 

Little Bear

Новичок
Хаааааа! Сделал! Всем еще раз огромное спасибо за вашу помощь! Все равно я по своему сделал, лень было переделывать всю базу и веб-приложение ))) Если-кому-то интересно станет, выложу код!

Еще раз спасибо
 
Сверху