Autor | Zpráva | ||
---|---|---|---|
time Profil * |
#1 · Zasláno: 7. 5. 2011, 11:49:40
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 |
#2 · Zasláno: 7. 5. 2011, 12:18:31
Š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 |
#3 · Zasláno: 7. 5. 2011, 12:49:59 · Upravil/a: TomášK
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 |
#4 · Zasláno: 7. 5. 2011, 13:05:39 · Upravil/a: Tori
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 * |
#5 · Zasláno: 7. 5. 2011, 15:41:22
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 |
#6 · Zasláno: 7. 5. 2011, 22:46:09
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 * |
#7 · Zasláno: 8. 5. 2011, 10:36:59
Děkuji za odpovědi a řešení :)
|
||
Časová prodleva: 13 let
|
0