[PHP] Sommare ore e minuti

Max61

Utente Attivo
2 Mar 2014
677
3
18
Salve, sono di nuovo a chiedere aiuto, questa volta nella somma delle ore, innanzitutto mi servirebbe sapere quale formato devo utilizzare visto che gli orari vengono inseriti in questo formato 00:00, poi vorrei sapere la sintassi corretta per le somme, io adesso la faccio così,
PHP:
( SUM(tot_oreferiali) + SUM(tot_orefestive) ) AS Tot_Ore_Fatte
ma non va bene perchè mi da somme di orari tipo 6.86 invece di 7.26.
Ho cercato in rete ma non sono riuscito a cavare un ragno dal buco...
mentre la somma tra i due subtotali la faccio così:
PHP:
$tot_ore = $tot_oreferiali + $tot_orefestive;
...
Grazie per la pazienza che avete
Max61
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Ipotizzo di avere una TBL di questo genere

Codice:
--
--
-- Create table "table1"
--
CREATE TABLE table1 (
  id int(11) DEFAULT NULL,
  ora time DEFAULT NULL,
  type varchar(255) DEFAULT NULL
)
La query per recuperare tutti i dati feriali è questa, analoga quella delle festività
Codice:
SELECT
  SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS sum
FROM table1
WHERE table1.type = 'feriale'
Per avere la somma di tutto
Codice:
SELECT
  SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS sum_tot
FROM table1

Una query completa per ricavare quello che ti interessa:
Codice:
SELECT
  (SELECT
      SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS feriali
    FROM table1
    WHERE table1.type = 'feriale') AS feriali,
  (SELECT
      SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS festivi
    FROM table1
    WHERE table1.type = 'festiva') AS festiva,
  SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS totale
FROM table1
Avendo questa base dovresti riuscire a fare ciò che ti serve!
 
Ultima modifica:

Max61

Utente Attivo
2 Mar 2014
677
3
18
Grazie, ho formattato la tabella e i campi di inserimento sono di tipo time, poi ho provato a lanciare la query da phpmyadmin
PHP:
SELECT
  (SELECT
      SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_oreferiali))) AS feriali
    FROM tblorario
    WHERE tot_oreferiali = tot_oreferiali) AS feriali,
  (SELECT
      SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive))) AS festivi
    FROM tblorario
    WHERE tot_orefestive = tot_orefestive) AS festiva,
  SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive))) AS totale
FROM tblorario
ma mi da questo risultato:
feriali 00:00:08
festiva 00:00:04
totale 00:00:04
forse è questo il problema?
PHP:
$tot_orefestive = date("H.i", strtotime($oraout_festive) - strtotime($orain_festive) - 3600) . " ore festive lavorate<br />\n";
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Ho modificato come mi hai detto,
PHP:
$tot_orefestive = date("hh:mm:ss", strtotime($oraout_festive) - strtotime($orain_festive) - 3600) . " ore festive lavorate<br />\n";
ma non calcola per niente la differenza tra l'uscita e l'entrata, allora ho provato così
PHP:
$tot_orefestive = date("h:m:s", strtotime($oraout_festive) - strtotime($orain_festive) - 3600) . " ore festive lavorate<br />\n";
ma la differenza è sbagliata...
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Ma parliamo di php o mysql?
Scusa non capisco cosa stai facendo....
Allora la somma degli orari da mysql, sono le query che ti ho inviato prima, quindi non capisco a cosa serva questo codice in php? Hai la somma delle feriali, festive e totali!
Le ore festive lavorate dovrebbero essere queste:
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(table1.ora))) AS sum FROM table1 WHERE table1.type = 'festiva'
Perchè l'hai riscritto in php....
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Cerco di spiegarmi se ci riesco, nella fase di inserimento dei dati nel db prima dell'insert faccio questo per calcolare sia le ore che il costo:
PHP:
/* LIVELLO BS5*/
    $livello = $_POST['livello'];
    if ($livello == 'BS5' && $orain_feriale >0 && !$orain_festive){
        $tot_oreferiali = date("hh:mm:ss", strtotime($oraout_feriale) - strtotime($orain_feriale) - 3600) . " ";               
        $costooraferiale = $costo_feriale;
    $costototferiale = $tot_oreferiali * $costooraferiale;
        $livello = $_POST['livello'];
} elseif ($livello == 'BS5' && $orain_festive >0 && !$orain_feriale) {
        $tot_orefestive = date("hh:mm:ss", strtotime($oraout_festive) - strtotime($orain_festive) - 3600) . " ";
        $costoorafestivo = $costo_festivo;
    $costototfestivo = $tot_orefestive * $costoorafestivo;   
        $livello = $_POST['livello'];
} elseif ($livello == 'BS5' && $orain_feriale >0 && $livello == 'BS5' && $orain_festive >0) {
        $tot_oreferiali = date("hh:mm:ss", strtotime($oraout_feriale) - strtotime($orain_feriale) - 3600) . " ";
        $costooraferiale = $costo_feriale;
        $costototferiale = $tot_oreferiali * $costooraferiale;
        $tot_orefestive = date("hh:mm:ss", strtotime($oraout_festive) - strtotime($orain_festive) - 3600) . " ";
        $costoorafestivo = $costo_festivo;
    $costototfestivo = $tot_orefestive * $costoorafestivo;
    }
    // FINE LIVELLO BS5 ********************************************************************
e in tabella vorrei trovare le ore giuste con l'importo corretto.
Probabilmente ho sbagliato approccio per fare quello che volevo...
Ciao
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Guarda, per i calcoli puoi effettuare quello che cerchi direttamente dal DB, aggiungendo (anche se i dati non saranno ottimizzati) alla tabella il Livello, con Ingresso ed Uscita...
In questo modo recuperi quello che cerchi con una banalissima query, senza impicciarti con il php (noteriamente più lento) per eseguire quello che ti serve.
Crea un trigger che all'evento insert faccia l'update del Costo:

Praticamente quando inserisci metti

id | Inizio | Fine | Tipologia | Livello | Costo

In una tabella di appoggio inserisci i vari livelli con costo orario, e solo dopo aver fatto l'insert di un nuovo record (escluso il costo), viene eseguito un trigger di aggiornamento sul record appena inserito.
In questo modo puoi aggiungere ed eliminare tutti i livelli che vuoi cambiando anche il costo orario, dato che hai il record sul db, senza spulciare codice per uniformare i dati.!
Fammi sapere!
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Allora, io ho già tutte le varie tabelle con i livelli dove sono già caricati i costi orari e in base al livello con il codice che ti ho postato recupero il costo e faccio i calcoli e mi sembra che la cosa sia corretta, il problema è che nel db le ore giornaliere sono corrette mentre il problema mi nasce nella somma delle ore di più giorni come nell'esempio che ho postato all'inizio, invece di 7.26 mostra 6.86...
ah la query della somma è questa
PHP:
SELECT *, (SUM(costototferiale) + SUM(costototfestivo)) AS Tot_costo FROM tblorario
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Per quanto riguarda le ore la sintassi è quella postata "SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive)))"
ossia trasforma i tempi in intero e sommali e successivamente converti l'intero in tempo.
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Scusami ma la query SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive))) dove la metto nell'insert?
O all'interno del codice che ti ho postato...
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
no quella non va nell'insert, solo nell'estrazione....
per l'insert devi formattare date('H:i:s',time())
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Buongiorno, soltanto adesso ho potuto provare il codice e sembra che funzioni correttamente, mi rimane una cosa da correggere: per stampare i parziali e i totali mensili creo una tabella con i dati presi dal db ma la somma mi da errore, allego query utilizzata:
PHP:
CREATE TABLE riepilogototalemese AS SELECT id, mese, anno, nominativo, matricola, livello, SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_oreferiali))) + SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive))),                                            (SUM(tot_oreferiali) + SUM(tot_orefestive)) AS totale_ore
 FROM tblorario WHERE mese='$mese' AND anno='$anno'
 GROUP BY mese, nominativo
se i totali li calcolo singolarmente 'SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_oreferiali)))' va bene altrimenti
SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_oreferiali))) + SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_orefestive)))
mi da questo errore:
Incorrect column name 'SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_oreferiali))) + SEC_TO_TIME(SUM(TIME_TO_SEC(tblorario.tot_'
mi sai dire dove sbaglio?
Grazie
Max61
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Perchè stai creando una Tabella in questo modo?
Quando crei una nuova tabella dovresti aggiungere il tipo di dato contenuto, quindi secondo me:
Non ho ottimizzato i dati, quindi vedi bene...

Codice:
CREATE TABLE test.test_1 (
  id int(11) NOT NULL AUTO_INCREMENT,
  mese varchar(255) DEFAULT NULL,
  anno varchar(255) DEFAULT NULL,
  nominativo varchar(255) DEFAULT NULL,
  matricola varchar(255) DEFAULT NULL,
  livello varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
)
ENGINE = INNODB
E la query che fai è questa:

Codice:
INSERT INTO test_1 (mese,anno,nominativo,matricola,livello)
     SELECT mese,anno,nominativo,matricola,livello
      FROM tabella_generale_dati WHERE mese = ? AND anno = ? AND nominativo =? AND livello = ?
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Ho provato a dichiarare i formati ma...sono una schiappa
allego codice utilizzato
PHP:
$sql = "CREATE TABLE test.test_1 (
  id int(11) NOT NULL AUTO_INCREMENT,
  mese varchar(255) DEFAULT NULL,
  anno varchar(255) DEFAULT NULL,
  nominativo varchar(255) DEFAULT NULL,
  matricola varchar(255) DEFAULT NULL,
  livello varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
)ENGINE = INNODB';

INSERT INTO test_1 (mese,anno,nominativo,matricola,livello)
     SELECT mese,anno,nominativo,matricola,livello
      FROM tblorario WHERE mese='$mese' AND anno='$anno'
                    GROUP BY mese, nominativo";
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Mese è numerico o intero????
Altra nota, prova così nel caso mese e anno siano numerici!
Codice:
$q="INSERT INTO test_1 (mese,anno,nominativo,matricola,livello)
     SELECT mese,anno,nominativo,matricola,livello
      FROM tblorario WHERE mese=$mese AND anno=$anno                    GROUP BY mese, nominativo";
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Il campo mese è testo varchar(255), il campo anno è numerico int(4), ho provato, mi crea la tabella ma vuota
codice:

PHP:
$sqlcreate = "CREATE TABLE gestioneorario.riepilogototalemese (
  id int(11) NOT NULL AUTO_INCREMENT,
  mese varchar(255) DEFAULT NULL,
  anno varchar(255) DEFAULT NULL,
  nominativo varchar(255) DEFAULT NULL,
  matricola varchar(255) DEFAULT NULL,
  livello varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
)ENGINE = INNODB";
// Execute query
if (mysqli_query($myconn,$sqlcreate))

$sql="INSERT INTO riepilogototalemese(mese,anno,nominativo,matricola,livello)
     SELECT mese,anno,nominativo,matricola,livello
      FROM tblorario WHERE mese=$mese AND anno=$anno";   
 
// Execute query
if (mysqli_query($myconn,$sql)) {
e mi da questo errore
Unknown column 'Aprile' in 'where clause'
non capisco dove trova la colonna Aprile' che guarda caso è il mese di lavorazione...
 

macus_adi

Utente Attivo
5 Dic 2017
1.265
82
48
IT/SW
Allora:
Codice:
$sql="INSERT INTO riepilogototalemese(mese,anno,nominativo,matricola,livello)
     SELECT mese,anno,nominativo,matricola,livello
      FROM tblorario WHERE mese=' ".$mese." ' AND anno=' ".$anno." ' ";
Guarda bene i quotes " ' "
 

Max61

Utente Attivo
2 Mar 2014
677
3
18
Niente da fare la tabella creata resta vuota e mi da questo errore nella pagina di visualizzazione della tabella
Notice: Undefined variable: mese in C:\xampp\htdocs\GestioneOrario\views\VisualizzaStampaStraordinariExcel.php on line 152

Notice: Undefined variable: anno in C:\xampp\htdocs\GestioneOrario\views\VisualizzaStampaStraordinariExcel.php on line 152
come vedi non trova i parametri che mi servono per visualizzare mese e anno corrente di lavoro