Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zliczenie godzin dla dowolnego zakresu
Forum PHP.pl > Forum > Bazy danych > MySQL
webdice
Witam,

mam problem ze zliczaniem czasu pracy dla godzin nocnych. Godziny nocne mamy od 22 do 6 rano. W jaki sposób ułożyć zapytanie które zliczy ilość godzin nocnych i zwykłych dla dowolnego zakresu godzin. Przykładowo:

  1. mając zmianę od 20 do 10, mamy 6 godzin zwykłych oraz 8 godzin nocnych,
  2. mając zmianę od 23 do 11, mamy 5 godzin zwykłych oraz 7 godzin nocnych,
  3. mając zmianę od 23 do 05, mamy 0 godzin zwykłych oraz 6 godzin nocnych,
  4. mając zmianę od 10 do 15, mamy 5 godzin zwykłych oraz 0 godzin nocnych


Chodzi mi po głowie rozwiązanie z warunkami, ale nie jest zbyt eleganckie.
vieri_pl
Dołączam się do pytania.

Znalazłem rozwiązanie w EXCEL'u: http://www.mrexcel.com/forum/showthread.php?t=427914

Na stacku też coś jest: http://stackoverflow.com/questions/8914360...tween-two-dates

Myślę, że może to ze stacka wystarczy przerobić i zrobić tablicę $hours z kluczami day, night?
Pilsener
Proste ify nie wystarczą, bo ktoś może zaczac zmianę np. o 21 a skończyć o 7 rano.

Dlatego ja bym się nie szczypał tylko dał 24 ify, po jednym dla każdej godziny, jeśli warunek jest spełniony dodajemy jeden do puli godzin nocnych lub dziennych. Niestety wtedy nici z elegancji, chyba, że użyjemy pętli:
http://dev.mysql.com/doc/refman/5.0/en/loop-statement.html

No i jest jeszcze kwestia minut, ale zakładam chodzi tylko o pełne godziny.
webdice
~vieri_pl rozwiązanie w PHP kompletnie mnie nie interesuje.

Kod
SELECT * FROM `TIME`;
+---------------------+---------------------+
| FROM                | TO                  |
+---------------------+---------------------+
| 2012-04-25 21:00:00 | 2012-04-25 07:00:00 |
| 2012-04-25 23:00:00 | 2012-04-25 07:00:00 |
| 2012-04-25 21:00:00 | 2012-04-25 05:00:00 |
| 2012-04-25 23:00:00 | 2012-04-25 05:00:00 |
| 2012-04-25 07:00:00 | 2012-04-25 19:00:00 |
| 2012-04-26 00:00:00 | 2012-04-26 06:00:00 |
+---------------------+---------------------+


  1. SELECT `FROM`, `TO`, SEC_TO_TIME( ( IF( `FROM` > `TO`, 1, 0 ) * IF( LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24, 16 / 24 ) < 0, 0, LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24,16 / 24 ) ) + GREATEST( 0, LEAST( 22 / 24, ( TIME( `TO` ) / 24 / 10000 ) + IF( `FROM` > `TO`, 1, 0 ) ) - GREATEST( 6 / 24, ( TIME( `FROM` ) / 24 / 10000 ) ) ) ) * 24 * 3600 ) AS `DAY`, SEC_TO_TIME( MOD( TIMEDIFF( TIME( `TO` ), TIME( `FROM` )) / 24 / 10000 + IF( SIGN( TIMEDIFF( TIME( `TO` ), TIME( `FROM` )) / 24 / 10000 ), 1, 0 ), 1 ) * 24 * 3600 - ( ( IF( `FROM` > `TO`, 1, 0 ) * IF( LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24, 16 / 24 ) < 0, 0, LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24,16 / 24 ) ) + GREATEST( 0, LEAST( 22 / 24, ( TIME( `TO` ) / 24 / 10000 ) + IF( `FROM` > `TO`, 1, 0 ) ) - GREATEST( 6 / 24, ( TIME( `FROM` ) / 24 / 10000 ) ) ) ) * 24 * 3600 ) ) AS `NIGHT` FROM `TIME`


Kod
+---------------------+---------------------+----------+----------+
| FROM                | TO                  | DAY      | NIGHT    |
+---------------------+---------------------+----------+----------+
| 2012-04-25 21:00:00 | 2012-04-25 07:00:00 | 02:00:00 | 08:00:00 |
| 2012-04-25 23:00:00 | 2012-04-25 07:00:00 | 01:00:00 | 07:00:00 |
| 2012-04-25 21:00:00 | 2012-04-25 05:00:00 | 01:00:00 | 07:00:00 |
| 2012-04-25 23:00:00 | 2012-04-25 05:00:00 | 00:00:00 | 06:00:00 |
| 2012-04-25 07:00:00 | 2012-04-25 19:00:00 | 12:00:00 | 00:00:00 |
| 2012-04-26 00:00:00 | 2012-04-26 06:00:00 | 00:00:00 | 06:00:00 |
+---------------------+---------------------+----------+----------+

6 rows in set (0.00 sec)

Przesadziłem, ale działa.
bpskiba
  1. SELECT `FROM`, `TO`, SEC_TO_TIME( ( IF( `FROM` > `TO`, 1, 0 ) * IF( LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24, 16 / 24 ) < 0, 0, LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24,16 / 24 ) ) + GREATEST( 0, LEAST( 22 / 24, ( TIME( `TO` ) / 24 / 10000 ) + IF( `FROM` > `TO`, 1, 0 ) ) - GREATEST( 6 / 24, ( TIME( `FROM` ) / 24 / 10000 ) ) ) ) * 24 * 3600 ) AS `DAY`, SEC_TO_TIME( MOD( TIMEDIFF( TIME( `TO` ), TIME( `FROM` )) / 24 / 10000 + IF( SIGN( TIMEDIFF( TIME( `TO` ), TIME( `FROM` )) / 24 / 10000 ), 1, 0 ), 1 ) * 24 * 3600 - ( ( IF( `FROM` > `TO`, 1, 0 ) * IF( LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24, 16 / 24 ) < 0, 0, LEAST( ( TIME( `TO` ) / 24 / 10000 ) - 6 / 24,16 / 24 ) ) + GREATEST( 0, LEAST( 22 / 24, ( TIME( `TO` ) / 24 / 10000 ) + IF( `FROM` > `TO`, 1, 0 ) ) - GREATEST( 6 / 24, ( TIME( `FROM` ) / 24 / 10000 ) ) ) ) * 24 * 3600 ) ) AS `NIGHT` FROM `TIME`

WOW
robi wrażenie
webdice
Źle wylicza minuty. Dla pełnych godzin działa prawidłowo. Mój post powinien być ukryty.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.