Autor Zpráva
time
Profil *
Mám v databázi tabulku, do které se mi ukládají časy ve formátu TIME (00:00:00 - %H:%i:%s), tyto časy tam mám dva - čas přihlášení (start_time) a čas odhlášení (end_time), dále tam pak mám ještě datum (date) ve formátu DATE (YYYY-MM-DD), pro každý přihlášení a odhlášení se vytvoří 1 záznam, který může vypadat třeba takhle - start_time=‘07:00:00‘, end_time=‘15:30:00‘, date=‘2011-05-07‘

Počet přihlášení pro daný den je neomezený, ale je kontrolováno, aby se nepřekrývali, tudíž se můžu přihlásit třeba v 7 ráno odhlásit 8 ráno, ale už se nemohu znovu přihlásit třeba v 7:30 v ten samí den ráno, ale můžu až v 8 ráno.

Takže když chci zjistit, jak dlouho trvalo přihlášení tak si vytvořím dotaz na databázi.
DB -> SELECT TIMEDIFF(end_time, start_time) AS hours FROM table_1 WHERE date='2011-05_07'
tenhle dotaz mi teda logicky vrátí proměnou $hours, která se bude rovnat 08:30:00

Tak teď si do DB přidám druhý záznam přihlášení: start_time=15:30:00, end_time=16:00:00, date=2011-05-07

Tak a tady nastává můj problém. Dotaz na DB o několik řádků víš, mě už nevrátí jeden výsledek, ale pole s dvěma výsledky, dejme tomu něco takového: $hours = array( [0] => "08:30:00", [1] => "00:30:00");

A já bych teď potřeboval nějakou funkci MySQL která by tyto hodnoty sečetla, ale zároveň proměnná $hours zůstala zachovaná a vrátila tedy výsledek 09:00:00 třeba do proměnné $total_time

takže něco jako DB->SELECT FUNCTION_SUM(TIMEDIFF(end_time, start_time) AS hours) AS total_time FROM table_1 WHERE date='2011-05-07' <- a tohle potřebuju, aby mi teda vrátilo dvě proměnné:
$hourst = array( [0] => "08:30:00", [1] => "00:30:00");
$total_time = "09:00:00";

Vím, že to lze udělat pomocí PHP, ale než se vrhnu do vymýšlení jak na to, tak bych to radši vyřešil už nějak v tom dotazu na DB, už jen kvůli rychlosti načítání, i když v tomhle případě je zanedbatelná.
Tori
Profil
Šlo by to třeba takhle (ale doufám, že existuje i lepší způsob):
SELECT `date`, SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`stop`, `start`)))) 'total' FROM tabulka GROUP BY `date`
TomášK
Profil
Dala by se použít konstrukce GROUP BY WITH ROLLUP, viz http://dev.mysql.com/doc/refman/5.0/en/group-by-modifiers.html
Tori
Profil
TomášK:
Můžete, prosím, napsat jak? Manuál jsem četla, zkoušela, leč nepřišla na to. Díky moc.

↓ [#6] Aha, myslela jsem, že to bude něco zásadně odlišného, co by se obešlo bez těch převodů na vteřiny a zpět.
time
Profil *
GROUP BY WITH ROLLUP v tomhle případě nemůže fungovat, protože:
wikipedia.org -
Výpis s konstrukcí WITH ROLLUP způsobí, že za standardním výpisem se objeví řádek s hodnotou NULL na místo sloupce, podle kterého jsou data agregována (je-li uveden), který znamená celkový údaj a na místě hodnoty agregační funkce pak hodnota za všechny právě uvedené výsledky těchto funkcí

takže jestli to chápu dobře tak aby to fungovalo, tak by TIMEDIFF musela být agregační funkce a to rozhodně není.
agregační_funkce = { COUNT | SUM | AVG | MIN | MAX } ([ ALL | DISTINCT ] výraz) | COUNT(*)
Ale nezkoušel jsem to.
TomášK
Profil
Agregační funkci je potřeba dodat - SUM, počítáme součet časů. Abychom měli ve výsledku intervaly pro každý záznam, je třeba groupovat podle nějakého klíče. Kromě toho MySQL převádí při sčítání čas na číslo, nevím o lepším způsobu než to převést na vteřiny a zpět. Příklad zde:
mysql> create table t1 (id int primary key auto_increment, start time, end time) ;
Query OK, 0 rows affected (0.04 sec)

mysql> insert into t1 values (1, '07:00:00', '15:30:00'), (2, '15:30:00', '16:00:00');
Query OK, 2 rows affected (0.00 sec)

mysql> select sec_to_time(sum(time_to_sec(timediff(end, start)))) from t1 group by id with rollup;
+-----------------------------------------------------+
| sec_to_time(sum(time_to_sec(timediff(end, start)))) |
+-----------------------------------------------------+
| 08:30:00                                            |
| 00:30:00                                            |
| 09:00:00                                            |
+-----------------------------------------------------+
3 rows in set (0.01 sec)
time
Profil *
Děkuji za odpovědi a řešení :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: