Sottrazione tra array

di pierpippo il
22 risposte

Salve a tutti, 

inizio con provare a fare il quadro di partenza:

ho un form dove ho vari campi tra cui uno è una select e come option prende i dati da un array che a sua volta è popolato dai dati prelevati da una tabella sql. Inserisco lo scorcio del codice del campo in questione:

<div id="tpl_fields" class="hidden">
      <div class="field">
         <label for="servizi-tpl">Linee da svolgere</label>
         <select class="listserv" name='servizi-tpl[]'multiple>
         <option value=''>Seleziona il servizio</option>
         <?php
         while ($riga = $servizi_da_svolgere -> fetch_assoc()) {
			$servizio_inserito = $riga['servizio'].'--'.$riga['partenza'].'--'.$riga['orario_corsa'];
			echo"
         <option value='$servizio_inserito'>
			$servizio_inserito
         </option>";
         }?>
         </select>
      </div>
   </div>

e questo è il codice che preleva i dati dalla tabella sql

if($data_servizio >= $inizio_invernale && $data_servizio <= $inizio_estivo){
                $query_linee_sql = "SELECT servizio,partenza,DATE_FORMAT(orario_corsa,'%H:%i') AS orario_corsa FROM gbgar_corse WHERE periodo='invernale' and frequenza='scolastica';";
                $servizi_da_svolgere = $Conn->query($query_linee_sql);
        }if ($servizi_da_svolgere == FALSE){
                die("Errore nell'esecuzione della query:" . $query_linee_sql);
        }

Questo è solo una cosa che provato a fare io per capire certe dinamiche ma il mio obiettivo sarebbe un tantino più complesso per cui volevo capire se il mio ragionamento è corretto prima di mettermi a scrivere codice inutilmente:

In pratica vorrei che quella variabile che ho chiamato $servizi_da_svolgere prima di essere passata al ciclo while per generare le option dovrebbe subire una scrematura:

Innanzi tutto ho un file.php dove ho pensato di determinare che "tipo" di data ho come riferimento, la quale può essere:

  • invernale o estiva se rientra in un determinato intervallo di date;
  • feriale;
  • festiva se è una domenica o se coincide con festività fisse (l'unico problema qui sarebbe gestire la Pasqua, o meglio il lunedì di pasqua che varia sempre in base alla data pasquale anche se cmq  il giorno di pasqua coincide con la domenica).
  • e poi può avere eccezioni  tra feriali compresi tra lun e ven e il sabato che a volte è da trattare come un feriale particolare.

Infatti la tabella "gbgar_corse" è cosi costituita:

MariaDB [gbgarage_test]> DESCRIBE gbgar_corse;
+--------------+------------------------------------------------------+------+-----+---------+----------------+
| Field        | Type                                                 | Null | Key | Default | Extra          |
+--------------+------------------------------------------------------+------+-----+---------+----------------+
| ID           | int(3)                                               | NO   | PRI | NULL    | auto_increment |
| TABELLA      | varchar(7)                                           | YES  |     | NULL    |                |
| PERIODO      | enum('estivo','invernale')                           | YES  |     | NULL    |                |
| SERVIZIO     | varchar(50)                                          | YES  |     | NULL    |                |
| PARTENZA     | varchar(20)                                          | YES  |     | NULL    |                |
| ORARIO_CORSA | time                                                 | YES  |     | NULL    |                |
| ARRIVO       | varchar(20)                                          | YES  |     | NULL    |                |
| FINE_CORSA   | time                                                 | YES  |     | NULL    |                |
| TEMPO_CORSA  | time                                                 | YES  |     | NULL    |                |
| KM           | float                                                | YES  |     | NULL    |                |
| FREQUENZA    | enum('feriale','scolastica','festiva','giornaliera') | YES  |     | NULL    |                |
| ECCEZIONI    | varchar(50)                                          | YES  |     | NULL    |                |
+--------------+------------------------------------------------------+------+-----+---------+----------------+
12 rows in set (0,001 sec)

Una volta determinato i tipo di data che ho, con delle if eseguo query select con diverse condizioni, sulla tabella di cui sopra, il tutto per giungere ad avere il mio array che potrei chiamare $servizi_da_evadere.

Partendo quindi da $servizi_da_evadere per arrivare a $servizi_da_svolgere devo prima fare una differenza tra array (credo),
e per poterlo fare devo prima estrarre i servizi già inviati per la stessa data, dalla tabella sql "servizi_inviati".

Quindi l' array contenuto in $servizi_da_svolgere deve risultare dalla differenza tra $servizi_da_evadere meno $servizi_inviati.

E mentre scrivo mi sorge la seguente domanda: se per una data non è stato ancora inviato nessun servizio la sottrazione di array come andrebbe gestita?

In ogni caso, dovrei ottenere che la mia select, quella che ho nel form, di mano in mano che vengono inviati servizi, e che quindi si popola la tabella "servizi_inviati", per la medesima data, mi darà sempre meno options perché quelle già usate verranno sottratte.

Lo scopo intuibile è ottenere da una parte con le condizioni a monte, delle option meno numerose tra cui selezionare i servizi da inviare, e dall'altro anche una sorta di controllo a prevenire l'assegnazione errata dello stesso servizio a due operatori diversi.

Dico giusto? 

Questo sarebbe il mio obiettivo, ma intanto devo capire col vostro aiuto se il ragionamento è fattibile && corretto.

Buona giornata a tutti e grazie comunque.

Filippo P.

22 Risposte

  • 22/05/2026 - pierpippo ha scritto:

    Partendo quindi da $servizi_da_evadere per arrivare a $servizi_da_svolgere devo prima fare una differenza tra array (credo),

    no, devi fare una query che ti da già il risultato che vuoi.

    a titolo di esempio

    SELECT
        c.servizio,
        c.partenza,
        DATE_FORMAT(c.orario_corsa,'%H:%i') AS orario_corsa
    FROM gbgar_corse c
    WHERE
        c.periodo = 'invernale'
        AND c.frequenza = 'scolastica'
    
        AND NOT EXISTS (
            SELECT 1
            FROM servizi_inviati s
            WHERE
                s.data_servizio = ?
                AND s.servizio = c.servizio
                AND s.partenza = c.partenza
                AND s.orario_corsa = c.orario_corsa
        )
    
  • Credo di avere un problema in questo caso:

    la tabella in cui vengono registrati  i servizi inviati ha una colonna unica che si chiama "servizi_da_svolgere" dove possono convogliare sia i servizi selezionati dalla tabella gbgar_corse, attraverso la select del form; sia informazioni scritte liberamente nella input "dettagli" del form, perché descrivono servizi non catalogabili nella tabella gbgar_corse.

    Non avevo previsto questa cosa quando avevo creato il form e le tabelle per cui ho solo concatenato in una unica stringa i valori delle colonne "servizio", "partenza" e "orario_corsa" per scriverle nella tabella gbgar_serv_slave, alla colonna "servizi_da_svolgere".

    ti metto il codice che scrive nella tabella:

    if($tipologia === "tpl" && !empty($servizi_tpl)){
            $sql_slave = "INSERT INTO gbgar_serv_slave (id_master,tipologia,macchina,servizi_da_svolgere) VALUES (?,?,?,?)";
            $stmt_slave = $Conn->prepare($sql_slave);
            foreach($servizi_tpl as  $servizio){
              $stmt_slave->bind_param("isss",$id_master,$tipologia,$macchina,$servizio);
              $stmt_slave->execute();
            }
          }if($tipologia === "noleggio" && !empty($dettagli)){
            $sql_slave = "INSERT INTO gbgar_serv_slave (id_master,tipologia,macchina,servizi_da_svolgere) VALUES (?,?,?,?)";
            $stmt_slave=$Conn->prepare($sql_slave);
            $stmt_slave->bind_param("isss",$id_master,$tipologia,$macchina,$dettagli);
            $stmt_slave->execute();
          }if($tipologia === "officina" && !empty($dettagli)){
            $sql_slave = "INSERT INTO gbgar_serv_slave (id_master,tipologia,macchina,servizi_da_svolgere) VALUES (?,?,?,?)";
            $stmt_slave = $Conn->prepare($sql_slave);
            $stmt_slave->bind_param("isss",$id_master,$tipologia,$macchina,$dettagli);
            $stmt_slave->execute();
          }
          echo"<div class='risposta'> Servizio registrato correttamente! </div>";  
      }else{
        echo"<div class='risposta'> Errore:" . $stmt_master->error . "</div>";
      }
    }

    Come si può vedere sulla base del valore selezionato per "tipologia" la query INSERT INTO cambia, cioè prende i valori da due diverse variabili che a monte prendo i valori delle chiavi ['servizi_tpl'] oppure ['dettagli'].

    Quindi non ho un' esatta corrispondenza tra le colonne della tabella gbgar_corse e gbgar_serv_slave.

    A sto punto la domanda è: come associo le colonne nella condizione "NOT-EXISTS" ?

    Occorre, penso, che in gbgar_serv_slave venga scritto anche un id_corsa, aggiungendo in tabella la relativa colonna per avere una colonna associabile?

    Cioè, se ho capito bene, con la sub-query aggiungo la condizione per la quale vengano estratti nella select principale, i record che non compaiono anche nella tabella provvisoria che creo nella subquery e che prende i valori dalla tabella che nel mio caso si chiama appunto gbgar_serv_slave.

    Quindi devo avere almeno una colonna associabile per individuare le corse già assegnate per la stessa data.

    Spero di aver capito bene ma se è cosi prima di procedere devo correggere la tabella gbgar_serv_slave e lo script che ci scrive dentro.

    Giusto?

    Filippo P.

  • Tutto quello che metti in un Array, se lo estrapoli da una query, quella.query è già un Array.

    Non ho capito bene cosa stai facendo, magari perché il mio cervello è più incline a lavorare su dati normalizzati.

    Hai una tabella servizi dove si descrivono i vari servizi che si possono fare. Come fosse una lista clienti che esistono e posso utilizzare.

    Può capitare che per un motivo x un cliente prima, di essere cliente, sia un potenziale cliente.

    Gli faccio un preventivo ma gli unici dati che ricevo sono telefono e ragione sociale.

    Se voglio sapere quanti clienti certi e potenziali ho cosa posso fare?

    Apro preventivi selezionando SOLO i clienti del campo clienti della tabella preventivi non presenti nella tabella clienti: hai fatto la tua prima sottrazione di Array tra l'array clienti e l'array select clienti da preventivi che non sono presenti nella tabella clienti as potenziali

    Quindi fai una addizione tra l'array clienti Union Array potenziali ed hai la lista di tutti quelli che hanno avuto un contatto (effettivi e potenziali)

    Chiusa questa parentesi, tutto quello che ti serve è nel db. Se riesci ad estrapolare i servizi da svolgere, i servizi svolti e tutti i servizi (potenziali ed effettivi) puoi risolvere il tutto con una query o una stored procedure o ambedue.

    Appena posso decifrare la struttura dei dati ti do una traccia.

    PS. Vedo una inserti.... Cicla la query come cicleresti un Array.

  • 23/05/2026 - pierpippo ha scritto:

    query INSERT INTO cambia, cioè prende i valori da due diverse variabili che a monte prendo i valori delle chiavi ['servizi_tpl'] oppure ['dettagli'].

    Sarebbe utile, in un automatismo, capirne la conditio.

    In base a cosa cambia?

    Hai provato a dividere il problema di grado 10 con due di grado 5? Cioè prima un criterio poi l'altro.

  • 23/05/2026 - pierpippo ha scritto:

    A sto punto la domanda è: come associo le colonne nella condizione "NOT-EXISTS" ?

    Nell'esempio dei potenziali clienti al netto di clienti hai tutti in non exist della tabella clienti.

    Sarebbe un inizio per automatizzare l'inserimento come nuovo cliente con la conditio "ho tutti i dati relativi ai campi da riempire".

    Ovviamente parlo in linea teorica.

  • 23/05/2026 - sihsandrea ha scritto:

    Non ho capito bene cosa stai facendo, magari perché il mio cervello è più incline a lavorare su dati normalizzati

    Dal momento che ho un form per gestire dei servizi,  dal forn ottengo dei dati che vanno registrati in un database, nella tabella serv_master e la sua collegata serv_slave. 

    In questa tabella ho la colonna servizi_da_svolgere. 

    Qui ci finiscono i dati che nel forn vengono inseriti nel campo tipo input 'dettagli' se non sono servizi fissi diciamo. 

    Oppure ci finiscono dati che nel form vengono selezionati in una select dove le options sono extrapolate dalla tabella 'corse', che sono servizi fissi. 

    Ma le corse son tante nel loro insieme e vorrei che  non venissero estrapolate sempre necessariamente tutte, ma in maniera condizionata in base al giorno di riferimento. 

    Per questo dicevo che devo determinare che data ho tra invernale, estiva, feriale etc.... 

    A sto punto, se sottraggo dalle corse che vanno fatte in una data, quelle che per la medesima data sono già state assegnate, man mano che  i sevizi vengono inviati al database ovvero scritti serv_slave, agli operatori (autisti), le option  nel form saranno quelle che ancora non son assegnate, così avrei un  intrinseco controllo per evitare che una corsa venga assegnata doppia o che resti inevasa.

    Questo è l'obbiettivo. 

    23/05/2026 - sihsandrea ha scritto:

    In base a cosa cambia?

    Qui mi riferivo allo script che riceve i dati dal form e li scrive nella tabella serv_master e serv_slave. 

    In base al valore selezionato in 'tipogia', nello steso form, che può essere tpl o noleggio, 

    la query INSERT INTO scrive nella colonna 'servizi_da_svolgere' il valore contenuto in $servizi_tpl oppure in $dettagli. 

  • 23/05/2026 - pierpippo ha scritto:

    In questa tabella ho la colonna servizi_da_svolgere. 

    In quale? Mella.master o nella detail?

    23/05/2026 - pierpippo ha scritto:

    dal forn ottengo dei dati che vanno registrati in un database, nella tabella serv_master e la sua collegata serv_slave. 

    Quindi hai dei campi di immissione da utente

    Se confermi true allora

    Insert bla bla valute campo per campo...

    Finito!

    A meno che i dati da inserita siano una elaborazione in base all'input dell'utente.

    23/05/2026 - pierpippo ha scritto:

    Qui ci finiscono i dati che nel forn vengono inseriti nel campo tipo input 'dettagli' se non sono servizi fissi diciamo. 

    Il programma non dice: esegue! Esegue in base all'input.

    23/05/2026 - pierpippo ha scritto:

    Oppure ci finiscono dati che nel form vengono selezionati in una select dove le options sono extrapolate dalla tabella 'corse', che sono servizi fissi. 

    Con quale.criterio? Ci sarà un radio Burton o una combobox suppongo.

    Se selezioni dalla combo "Pippo" esegui la query load query Pippo

    23/05/2026 - pierpippo ha scritto:

    Ma le corse son tante nel loro insieme e vorrei che  non venissero estrapolate sempre necessariamente tutte, ma in maniera condizionata in base al giorno di riferimento

    Where (date tra a e b e variabile usa data=true)

    Se false le estrapola tutte

    23/05/2026 - pierpippo ha scritto:

    Per questo dicevo che devo determinare che data ho tra invernale, estiva, feriale etc.... 

    Questi li crei a parte in una tabella 

    Id descrizione dal al

    E la metti in relazione alla Where (date tra a e b e variabile usa data=true) di prima

    23/05/2026 - pierpippo ha scritto:

    A sto punto, se sottraggo dalle corse che vanno fatte in una data, quelle che per la medesima data sono già state assegnate,

    Sono autisti? Alimenti la tabella turni

    Finché not in turni where date...

    23/05/2026 - pierpippo ha scritto:

    ovvero scritti serv_slave, agli operatori (autisti), le option  nel form saranno quelle che ancora non son assegnate, così avrei un  intrinseco controllo per evitare che una corsa venga assegnata doppia o che resti inevasa.

    Chiama le tabelle in modo naturale, con carta e penna scrivi che sono turni. Apri il diario e scrivi o rettifichi quando un autista non può onorare il turno perché malato.

  • 23/05/2026 - sihsandrea ha scritto:

    In quale? Mella.master o nella detail?

    In serv_slave (o detail come la chiami tu)
    (tutte le tabelle hanno prefisso gbgar_ che ora ometto. Questo perchè poi, fatti test, le devo spostare nel database del progetto che è basta su CMS Joomla e che richiede la presenza del prefisso definito in configuration.php)

    23/05/2026 - sihsandrea ha scritto:

    Quindi hai dei campi di immissione da utente

    Se confermi true allora

    Insert bla bla valute campo per campo...

    Finito!

    Il form lo sto testando al di fuori del CMS, poi apporto le modifiche che ho apportato nel form creato nel CMS appunto che è inserito in un articolo .

    Penso che si sappia come nei cms i  contenuti vengano creati attraverso un editor che crea degli  articoli che poi sono agganciati ad una voce di menu per essere raggiungibili da front end.

    Per poter creare dei contenuti come quelli del form tuttavia mi sono avvalso di un plug in, l'unico che uso al di fuori del core del cms, cioè creato da terze parti, che permette di inserire codice direttamente nell'articolo.

    Altri componenti esterni, compresi quello per creare form non lo uso perchè poi nn so mai se viene mantenuto aggiornato.

    Lo stesso varrebbe per "sourcerer" che uso per inserire appunto codice negli articoli ma questo negli anni non ha mai dato problemi.

    L'articolo che contiene il form non sarà raggiungibile da tutti gli utenti.

    Uso joomla appunto per avere tutto il suo sistema di utenti, gruppi e accessi ai contenuti, già pronto.

    Il front end ha solo una pagina generale visualizzabile pubblicamente da utenti  guest.

    Quasi tutte le voci del menu appaiono solo se si fa login, quindi agli utenti "registered".

    Gli utenti registered sono invece gli addetti ai lavori che entrano per conoscere informazioni tra cui i servizi che devono effettuare di giorno in giorno.

    Ovviamente tra  i registered ho due utenti che è sono anche "author" e possono dal loro front end visualizzare l'articolo che contiene il form che sto sviluppando.

    23/05/2026 - sihsandrea ha scritto:

    Con quale.criterio? Ci sarà un radio Burton o una combobox suppongo.

    Il criterio è una select in cui nel form puo essere scelto tpl o noleggio.

    Con java ottengo che in base al click compaia il div che contiene la label "dettagli" con una input 

    oppure

    se si sceglie tpl appare una select in cui le options sono un elenco di corse che vanno evase, lista che però vorrei "filtrare" appunto secondo la data di riferimento affinché mostri le corse che effettivamente vanno evase nel giorno specifico (non tutte quindi, ad es. se i giorno è festivo verranno visualizzate solo quelle che sono esclusivamente festive o giornaliere); e anche in base a quelle già assegnate che man mano devono sparire dalla lista.

    Quindi dicevo che prima determino la data. 

    Essa a sto punto è in $SESSION['data'];

    cosi non va inserita ad ogni compilazione.

    Viene settata in un form che sta a monte di quello principale dove viene impostata la data cui si riferiscono i servizi che vengono registrati nel database e quindi al tempo stesso resi disponibili a chi li deve consultare, ma anche settare le date in cui finisce e inizia l'orario invernale ed estivo, date che differiscono di anno in anno seppur di pochi giorni.

    Prima verifico se la data rientra nel periodo estivo o invernale.

    Poi devo avere in una tabella le date festive fisse (1 gen, 6 gen etc....),

    Non so come gestire il festivo Pasquale e relativo Lunedì di Pasqua.  

    le estrapolo e  verifico che la data di riferimento è oppure no tra queste, e se non è una domenica.

    se è feriale devo determinare anche se non è un sabato.

    e poi predispongo le query select sulla tabella "corse" sulla base dei confronti che mi hanno determinato che tipo di data ho .

    In esse, oltre alle condizioni relative al tipo di data, devo aggiungere la condizione NOT EXISTS che mi hai già suggerito per ottenere una lista già epurata dei servizi già presenti nella tabella serv_slave, ovviamente per la stessa data. 

    Io ho capito cosi.

    Un po complicato ma una volta che funziona dovrebbe essere comodo come sistema per distribuire i servizi . 

    Buona serata

    Filippo P

  • Al momento non posso rispondere. Leggo i dati che hai e ti indirizzo su come fare la query.

  • 24/05/2026 - pierpippo ha scritto:

    In serv_slave (o detail come la chiami tu)

    In ambito tabelle una relazione viene identificata come master per la tabella madre e detail per la tabella figlia.

    In ambito database, master è il database principale, quello che contiene i dati e ne permette l'archiviazione o la modifica o l'eliminazione, slave identifica un database replica locale o un nodo.

    Chiusa parentesi.

    Andiamo per gradi.

    Lato amministratore tabelle.e.campi al minimo sindacale:

    Dati basilari

    Carichi i giorni festivi nelle tabella festività{id; data; descrizione;} Carichi le feste principali e poi automatizzi i sabati e le domeniche

    Carichi i periodi (estivo/invernale) nella tabella.periodi{id; descrizione(estivo/invernale); dal; al;}

    Carichi i prrcorsi{id; luogopartenza; luogoarrivo;}

    Carichi gli autisti{id; nome;

    Creazione turni autisti

    Turni{id; data; dalle; alle; autista;}

    Orari{id; ora partenza; percorso id; estivo(s/n); festivo(s/n); ecc....} Tutti flag che determinano in base alla data quante corse per ogni percorso ci sono per quella data (presa dalla tabella festività). Se vuota è feriale e se rientra nel range può essere estivo o invernale ma tu visualizzi solo le corse che rispondono ai criteri impostati.

    Carichi le corse{id; codice corsa; nrfestivo; nei verbale; nrestivo; ora partenza;;  autista;}

    Qui, supponendo che in inverno abbiamo 5 corse da lun a ven

    Adesso hai tutte le corse e tutti gli autisti per data

    Selezioni una data e hai una lista di corse ed una lista di autisti

    Devi popolare una tabella corsa autista che lega le corse agli autisti.

    CREATE TABLE festivita (
        id INT AUTO_INCREMENT PRIMARY KEY,
        data DATE NOT NULL UNIQUE,
        descrizione VARCHAR(255));
    Mostra un elenco con le core da assegnare
    
    SELECT
        o.id,
        o.ora_partenza,
        p.luogo_partenza,
        p.luogo_arrivo
    
    FROM orari o
    
    JOIN percorsi p
    ON p.id = o.percorso_id
    
    WHERE o.attiva = 'S'
    
    AND o.periodo = 'estivo'
    
    AND o.festivo = 'N'
    
    AND o.giorno_settimana = 3
    
    AND o.id NOT IN (
    
        SELECT a.orario_id
        FROM assegnazioni a
        WHERE a.data = '2026-07-15'
    )
    
    ORDER BY o.ora_partenza;

    E gli autisti ancora disponibili

    SELECT 
      a.id,
      a.nome,
      t.dalle,
      t.alle
    FROM autisti a
    INNER JOIN turni t
      ON t.autista_id = a.id
    WHERE t.data = '2026-05-25'
      -- puoi mettere un parametro
      -- l'autista deve essere nel turno
      AND '10:00:00' BETWEEN t.dalle AND t.alle
     -- NON deve avere già una corsa assegnata a quell'ora
      AND NOT EXISTS (
         SELECT 1
         FROM corsa_autista ca
         INNER JOIN corse c
            ON c.id = ca.corsa_i                 
            WHERE ca.autista_id = a.id                                                     
            AND c.data = '2026-05-25'                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
            );

    Selezioni la corsa disponibile, l'autista disponibile e al click fai la insert poi refresh delle.due sql

  • 25/05/2026 - sihsandrea ha scritto:

    n ambito tabelle una relazione viene identificata come master per la tabella madre e detail per la tabella figlia.

    In ambito database, master è il database principale, quello che contiene i dati e ne permette l'archiviazione o la modifica o l'eliminazione, slave identifica un database replica locale o un nodo.

    Ops... ok ho capito. Ho usato il termine che conoscevo per opposto a master, cioè slave e ho usato quel nome per identificare la tabella. In effetti in questo caso è diverso.

    Per il resto ora pian piano cercherò di capire cosa mi hai scritto.

    Grazie 

  • Mi son rimesso a guardare quanto mi suggerisci ma francamente sono perplesso.

    Procedendo per gradi, e nel mio caso i gradi devono avere alzate di pochi cm, devo "semplicemente" determinare per ora quali corse devono popolare la var array $servizi_da svolgere.

    E' su di essa che nel form il ciclo while lavora per darmi delle options in una select dove è possibile cliccare per selezionare quali corse assegnare.

    Al momento ho determinato solo il valore di $orario_in_vigore che corrisponde a estivo o invernale in base al valore di $data_servizio.

    Quindi lo script seguente mi popola l'array $servizi_da_svolgere solo in base all'orario in vigore. 

    segue lo script 

    <?php
    session_start();
    $data_servizio = $_SESSION['data'];
    $inizio_invernale = $_SESSION['inizio_invernale'];
    $inizio_estivo = $_SESSION['inizio_estivo'];
    
    
    //DETERMINAZIONE DELLA DATA
    
    if($data_servizio>=$inizio_invernale && $data_servizio<=$inizio_estivo){
            $orario_in_vigore="invernale";
    }else{
            $orario_in_vigore="estivo";
    }
    
    
    //determinzaione valore di $servizi_da_svolgere
    
    if($orario_in_vigore==="invernale"){
            $query_linee_sql = "SELECT id_corsa,servizio,partenza,DATE_FORMAT(orario_corsa,'%H:%i') AS orario_corsa FROM gbgar_corse WHERE periodo='invernale' and frequenza='scolastica';";
            $servizi_da_svolgere = $Conn->query($query_linee_sql);
    }elseif($orario_in_vigore==="estivo"){
            $query_linee_sql = "SELECT id_corsa,servizio,partenza,DATE_FORMAT(orario_corsa,'%H:%i') AS orario_corsa FROM gbgar_corse WHERE periodo='estivo';";
            $servizi_da_svolgere = $Conn->query($query_linee_sql);
    }elseif ($servizi_da_svolgere == FALSE){
            die("Errore nell'esecuzione della query:" . $query_linee_sql);
            }
    ?>

    quindi poi vanno inseriti tutti gli altri confront per determinare se per  il valore di $data_servizio:

    oltre ad avere $orario_in_vigore con valore invernale o estivo,

    posso anche avere:

    $frequenza con valore festivo, feriale, scolastico, giornaliero
    e
    $eccezioni che può ad es avere  valore tipo "solo sabato". (alcune corse si fanno solo sabato come potenziamento servizio in aggiunta alle ordinarie)

    Per ora mi accontento di far funzionare bene questo meccanismo e poi mi occuperò, se non ho capito male, di inserire le subquery per eliminare di volta in volta gli id dalla tabella gbgar_corse che per la stessa data sono già usati, cioè appaiono già in gbgar_servizi_assegnati.

    Grazie e buona domenica.

  • Intanto devi caricare i dati.

    Poi la query che va azzerando la lista è così 

    https://uploadnow.io/f/QGGRHxB

    E questo è quello che fa

    https://uploadnow.io/f/YSTBG67

    Tu aggiungi id tabella 1, id tabella 2 efai un requery

    Lo stesso se cancelli il record della terza tabella: basta fare un requery

    La prima tabella, nel tuo caso, mostra le corse (viene fuori da una select per giorno o mese o quello che vuoi).

    La seconda tabella tira fuori gli autisti

    La terza tabella va scalando la seconda. Io nel mio esempio ho solo la queri per la seconda tabella ma il concetto vale anche per la prima tabella.

  • Ho avuto un'idea diversa:

    innanzi tutto ho aggiunto la chiave esterna alla tabella sql  "gbgar_serv_detail" (ho corretto il nome della tabella).

    La  chiave esterna l'ho attribuita alla colonna id_corsa ed è collegata all'omonima colonna della tabella gbgar_corse.

    Poi nel form dove appaiono le corse nella tendina che ospita le options invece di prelevare solo la descrizione della corsa ho aggiunto all'attributo value anche id_corsa.

    <select class="listserv" name='servizi-tpl[]'multiple>
             <option value=''>Seleziona il servizio</option>
             <?php
             while ($riga = $servizi_da_svolgere -> fetch_assoc()) {
    			$corsa_inserita = $riga['servizio'].'--'.$riga['partenza'].'--'.		    $riga['orario_corsa'];
             $id_corsa = $riga['id_corsa'];
    			echo"
             <option value='$corsa_inserita|$id_corsa'>
    			$corsa_inserita
             </option>";

    Cosi ottengo che:  

    $_POST['servizi-tpl'];   contiene due stringhe che come vedi in seguito vado ad esplodere nel ciclo foreach:

    if($tipologia === "tpl" && !empty($servizi_tpl)){
            $sql_slave = "INSERT INTO gbgar_serv_detail(id_master,tipologia,macchina,servizi_da_svolgere,id_corsa) VALUES (?,?,?,?,?)";
            $stmt_slave = $Conn->prepare($sql_slave);
            foreach($servizi_tpl as  $stringa){
              $dato_corsa = explode('|',$stringa);
              $info_corsa = $dato_corsa[0];
              $id_corsa = $dato_corsa[1];
              $stmt_slave->bind_param("isssi",$id_master,$tipologia,$macchina,$info_corsa,$id_corsa);
              $stmt_slave->execute();
            }

    Insomma ora la tabella gbgar_serv_detail contiene anche l'id della corsa inserita in ogni riga.

    Ora quando sistemo la query select che mi tira su i valori per le option ho modo di usare la subquery

    per escludere il prelievo delle righe dove il valore di id_corsa esiste già in gbgar_serv_detail.

    Se funzia ti aggiorno.

    Se non ho capito male in questo modo ho solo una ridondanza di dati in database:

    i valori delle colonne ID CORSA SERVIZIO, PARTENZA E ORARIO appariranno identiche in due tabelle mentre forse sarebbe stato corretto inserire solo id_corsa in gbgar_serv_detail e poi nel file che mostra le corse assegnate nel prospetto generale e in quello visto dai singoli operatori avrei potuto inserire una join.

    Cmq per ora mi accontento di far funzionare bene la select html con le sue option che man mano per la stessa data deve evitare di mostrare le options già assegnate.

    Buona serata  e buona settimana

    Filippo P.

Devi accedere o registrarti per scrivere nel forum
22 risposte