Selezionare con Distinct per raggruppare

di il
14 risposte

Selezionare con Distinct per raggruppare

Per un mini registro presenze che provavo a fare per imparare qualcosina  ho 3 tabelle
Squadre (id squadra)
Nominativi (id nome cognome id_squadra etc)
Presenze (id id_nominativo datapresenza tipopresenza)

Allego Nominativi e Presenze (Squadre è semplice e non la carico)

Come evidenziato ci sono stati 3 allenamenti (3 date).  Ecco... Da una parte ho già detto che sto lavorando (una var $idteam) con una squadra o con un'altra. 
Per cui vorrei mostrare le date degli allenamenti che gli atleti di Squadra1 (con id=1) hanno effettuato. Se invece sto lavorando dentro Squadra2 vorrei vedere solo le date che interessano gli atleti di Squadra2. 

Ho fatto così 

SELECT DISTINCT Presenze.DataPresenza, Nominativi.id_squadra FROM Presenze,Nominativi WHERE Nominativi.id_squadra='1' ORDER BY DataPresenza DESC;

Ottenendo questo

MA se cambio l'id della squadra e metto 2 ottengo lo stesso risultato di 3 date. MA in realtà gli atleti di Squadra2 non hanno fatto gli stessi allenamenti di quelli di Squadra1. Hanno fatto solo 2 date.  Il 01-11-2024 non si sono allenati e quindi non dovrei vederlo nella lista. 

 

Perdonate la mia inesperienza. Forse la mia query è sbagliata.  Quale potrebbe essere il problema? E come lo risolvo?

14 Risposte

  • Re: Selezionare con Distinct per raggruppare

    Tu stai usando DUE tabelle, e metti un filtro solo su una 

    MA

    non metti nessuna condizione che lega una tabella all'altra.

    in questo caso viene fatto, banalmente, il ‘prodotto cartesiano’ dei record delle tabelle.

    quello che ti serve e' una JOIN.

    si chiama ‘teoria relazionale dei dati’ o 'modello relazionale'

    https://it.m.wikipedia.org/wiki/Modello_relazionale

    https://it.m.wikipedia.org/wiki/Normalizzazione_(informatica) 

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - ricmanx ha scritto:


    SELECT DISTINCT Presenze.DataPresenza, Nominativi.id_squadra FROM Presenze,Nominativi WHERE Nominativi.id_squadra='1' ORDER BY DataPresenza DESC;

    ma vuoi vedere anche i nomi dei giocatori?

    se non ti serve sapere chi ha giocato o si è allenato nella squadra togli nominativi altrimenti leghi nominativi a presenze: 

    inner join nominativi on presenze.idsquadra=nominativi.idsquadra

    e la virgola tra presenze e nominativi la fai saltare pure…

    tuttavia…

    12/11/2024 - ricmanx ha scritto:


    vorrei mostrare le date degli allenamenti

    ergo ti manca un'altra clausola nella where:

    and tipopresenza='a'

    se invece ti interessano le partite:

    and tipopresenza='p'

    sei lo stesso che ha problemi con “OR”?

    non si va per tentativi… si studia.

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - migliorabile ha scritto:


    quello che ti serve e' una JOIN.

    si chiama ‘teoria relazionale dei dati’ o 'modello relazionale'

    https://it.m.wikipedia.org/wiki/Modello_relazionale

    https://it.m.wikipedia.org/wiki/Normalizzazione_(informatica) 

    Grazie. Sto leggendomi qualcosa.... (siccome queste cose le faccio solo per mio diletto devo usare i ritagli di tempo). 

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - sihsandrea ha scritto:


    ma vuoi vedere anche i nomi dei giocatori?

    No. In questo caso volevo solo trovare le date - senza doppioni - degli allenamenti svolti. Poi una volta mostrata come link la lista degli allenamenti svolti cliccandoci sopra andrei in una pagina che mi mostra l'elenco dei giocatori per "stato" (presenti/assenti/ritardatari) relativi a quella sessione di allenamento. 

    Solo che come la ho impostata io non funziona perche (come mi è stato fatto presente sopra) non ho messo in relazione le tabelle. 

    La tabella Nominativi l'avevo infilata nella query perchè lì dentro c'è il legame Nominativi.id (del nominativo) con l'id della squadra (Nominativi.id_squadra)

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - ricmanx ha scritto:


    Solo che come la ho impostata io non funziona perche (come mi è stato fatto presente sopra) non ho messo in relazione le tabelle. 

    La tabella Nominativi l'avevo infilata nella query perchè lì dentro c'è il legame Nominativi.id (del nominativo) con l'id della squadra (Nominativi.id_squadra

    Inner join è una relazione.

    In effetti, anche se sotto forma di briciole, ti ho scritto cosa manca.

    In generale:

    Select quello che vuoi from tabella1 inner join tabella2 on tabella1.campoincomune=tabella2.campoincomune

    Inner join altratabella on altricampi=altrolink

    Where tabella1.campox=parametrox and tabella2.campoy=parametroy

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - sihsandrea ha scritto:


    In generale:

    Select quello che vuoi from tabella1 inner join tabella2 on tabella1.campoincomune=tabella2.campoincomune

    Inner join altratabella on altricampi=altrolink

    Where tabella1.campox=parametrox and tabella2.campoy=parametroy

    Ok. Così unisco le tabelle in una unica “tabellona” (non sto a scegliere i campi e uso * per velocizzare la scrittura/lettura)

    SELECT * FROM Nominativi 
    INNER JOIN Presenze 
    ON Nominativi.id=Presenze.id_nominativo 
    WHERE Nominativi.id_squadra=1

    Tipo così (vedi sotto). MA non riesco a raggruppare le date. Sto anche provando a mettere delle sottoquery tra parentesi ma non ce n'è una che funzioni! Non avessi avuto bisogno della tabella Nominativi avrei fatto una SELECT DISTINCT su Presenze.DataPresenza

    In pratica il risultato che vorrei ottenere da questa tabella è semplicemente

    2024-09-03
    2024-11-01

    Non lo so... Forse non c'è una query in grado di raggruppare come voglio io. Forse dovrei aggiungere un campo id_squadra ANCHE nella tabella presenze. Ma mi sembrava una ripetizione averlo sia su Nominativi che su Presenze quando ho già un legame Nominativi.id con Presenze.id_nominativo …

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - ricmanx ha scritto:


    Non lo so... Forse non c'è una query in grado di raggruppare come voglio io.

    se hai:

    id     testo    data

    1      pippo   01/01/24

    2     pluto     01/01/24

    3      pippo   02/01/24

    per raggruppare non devi avere record eterogenei.

    nell'esempio, per raggruppare per campo testo

    select distinct testo bla bla

    ottieni 

    pippo

    pluto

    select distinct data bla bla

    ottieni

    01/01/24

    02/01/24

    nel tuo caso se vuoi raggruppare per data:

    select distinct datapresenza, idsquadra from bla bla…

    ottieni

    squadra 1 3/9/24

    squadra 1 1/11/24

    cerca di capire cosa vuoi mostrare.

    quando uso distinct e quando uso group by?

    un link esaustivo lo trovi qui (uno a caso): https://www.geeksforgeeks.org/select-distinct-vs-group-by-in-mysql/

    buona lettura.

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - sihsandrea ha scritto:


    cerca di capire cosa vuoi mostrare.

    Intanto ti ringrazio di tutte le dritte. 

    Riguardo al capire cosa mostrare effettivamente forse non sono stato in grado di dirlo bene (dentro di me l'ho capito). 

    Faccio un esempio. Sono un allenatore di due squadre (o n squadre) e voglio tenere un registro presenze di entrambe. Entro nel sito e scelgo quale squadra guardare (Squadre.id=1). Guardo i nominativi relativi a quella squadra (Select * from Nominativi  where Nominativi.id_squadra=1). Adesso vado nella pagina Presenze e da qui vorrei fare due cose 1) aggiungere le presenze dell'allenamento di oggi e 2) vedere la lista delle date di allenamento passate così da poterci cliccare sopra per andare a vedere l'elenco giocatori che hanno fatto parte dell'allenamento (o che erano assenti o arrivati in ritardo). 

    E qui sul punto 2) che non riesco a fare la query giusta di cui stiamo parlando. Perchè il giorno “ieri” si sono allenati dei giocatori della Sq1 ma il giorno "ierilaltro" Si sono allenati giocatori di entrambe le squadre (in orario differente). Quindi quando mostro la lista di Sq1 dovrei vedere solo la data di “ieri” mentre se vado su Sq2 dovrei vedere due date - ieri e ierilaltro - perchè i giocatori di Sq2 hanno fatto due sessioni di allenamento   

    Non so se riesco a esprimere bene il mio problema... 

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - ricmanx ha scritto:


    Riguardo al capire cosa mostrare effettivamente forse non sono stato in grado di dirlo bene (dentro di me l'ho capito). 

    si lo avevo capito, forse mi sono espresso male io o hai pensato che ti scrivessi la query…

    reset!

    13/11/2024 - ricmanx ha scritto:


    Sono un allenatore di due squadre (o n squadre) e voglio tenere un registro presenze di entrambe. Entro nel sito e scelgo quale squadra guardare (Squadre.id=1).

    suppongo in php(?!)

    testa:

    select * from squadre

    in testa hai un elenco delle qsuadre che gestisci. se selezioni una squadra, in base all'id della squadra (esempio la schiap per citare franco e ciccio)

    accanto hai la tabella dei giocatori in base alla selezione della squadra (prelevi l'id)

    select * from nominativi where idsquadra=[idprelevato]

    adesso vuoi vedere le presenze?

    come sopra selezioni il nominativo e vedi:

    presenze: opzioni{presente, ritardo, assente, tutti}

    select * from presenze 
    where id_nominativo=[idselezionato] 
          and  datapresenza=[parametrochevuoitu] 
          and tipopresenza=[opzioni] 
    order by datapresenza

    e vedi l'elenco delle presenze (valuta di inserire sempre la data registrando l'assenza senza lasciare la data null)

    se non vuoi scrivere le varie combinazioni di query:

    select * from presenze 
    where ((id_nominativo=[idselezionato] and variabilelogica=true) or variabilelogica=false) // se false mostra tutti
          and  ((datapresenza=[parametrochevuoitu]) and variabilelogica1=true) or variabilelogica1=false)  // se false mostra tutti
          and (tipopresenza=[opzioni] ) and variabilelogica2=true) or variabilelogica2=false) // se false mostra tutti
    order by datapresenza

    variabilelogica che potresti chiamare come meglio credi, la setti true se da un radiobutton selezioni “mostra tutti”.

    ti ho detto cerca di capire cosa visualizzare perchè la stessa query potrebbe cambiare non perchè non ti ho capito.

    tra le parentesi quadre vanno i parametri o le variabili che settano il valore.

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - ricmanx ha scritto:


    Perchè il giorno “ieri” si sono allenati dei giocatori della Sq1 ma il giorno "ierilaltro" Si sono allenati giocatori di entrambe le squadre (in orario differente). Quindi quando mostro la lista di Sq1 dovrei vedere solo la data di “ieri” mentre se vado su Sq2 dovrei vedere due date - ieri e ierilaltro - perchè i giocatori di Sq2 hanno fatto due sessioni di allenamento

    leggo solo ora…

    il formato data ha sia la data che l'orario esempio 01/01/2024 12:15:45

    select date(datapresenza) estrae 01/01/2024 per esempio

    select time(datapresenza) estrae 12:15:45

    adesso sai cosa fare…

    anche se in ogni caso per la prima richiesta ti serviva sapere se quel giorno pippo era presente o assente o ritardatario e se assente l'orario lascia il tempo che trova.

    Speriamo almeno che l'allenamento non sia un derby.

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - sihsandrea ha scritto:


    Speriamo almeno che l'allenamento non sia un derby.

    E invece si. Cioè ci sono volte in cui si allenano con un altro allenatore nella stessa fascia oraria!!! -_-

    Ma a parte questo la selezione Squadra1 e Squadra2 me le distingue tranquillamente senza scomodare anche gli orari. 

    Comunque tu nel suggerimento della query mi aiuti sul cercare gli atleti (where id_nominativo=[idselezionato]) io invece sono al passo più indietro. Che è mostrare un elenco di date relative al gruppo Squadra2 (o N che gli passo io come var in PHP). E che visivamente è esattamente quello che viene fuori da una "SELECT DISTINCT Presenze.DataPresenze FROM Presenze" (uno stupido elenco raggruppato di date una sotto l'altra in cui succede qualcosa). MA queste date dovrebbero essere relative solo alla Squadra2 (o cmq la selezionata). Invece non lo sono. Perchè se un atleta di Squadra1 si allena nella stessa data di qualcuno di Squadra2 allora viene aggiunta tale data nella lista date allenamento. ANCHE se faccio una Join tra Nominativi e Presenze qualsiasi “Where Nominativi.id_squadra=1” non filtra come pensavo succedesse. 

    Oppure non ho capito il tuo suggerimento 

  • Re: Selezionare con Distinct per raggruppare

    12/11/2024 - ricmanx ha scritto:


    Presenze (id id_nominativo datapresenza tipopresenza)

    Escucimi… in spagnolo.

    Li ho presi da qui.

    Presenze manca di idsquadra, ergo devi inserirlo con una join a nominativi.

    Dopo from presenze:

    Inner join nominativi on bla bla…

    E nella where aggiungi anche 

    And ((nominativi.squadra=[parametrosquadra] and flagsquadra=true) or flagsquadra=false))

    Così puoi visualizzare tutte le combinazioni.

  • Re: Selezionare con Distinct per raggruppare

    13/11/2024 - sihsandrea ha scritto:


    And ((nominativi.squadra=[parametrosquadra] and flagsquadra=true) or flagsquadra=false))

    OK ora ho capito e sono riuscito a farlo funzionare (alleluja!!!). 

    Ho usato la prima parte del tuo And perchè la seconda non l'ho capita. Cioè la parte con i flagsquadra true o false intendo. 

    Ormai che ci siamo se quando hai un minuto mi dici cosa sono te ne sarei grato... 

  • Re: Selezionare con Distinct per raggruppare

    And ((nominativi.squadra=[parametrosquadra] and flagsquadra=true) or flagsquadra=false))

    1)                                              se questa è vera                                                                questa è falsa

     2)                                             se questa è falsa                                                                questa è vera

    la query esegue la parte vera

    nel primo caso oltre a true si trova l'istruzione squadra=valore

    nel secondo caso non viene passata l'istrizione squadra=valore

    se fosse stato:

    And ((nominativi.squadra=[parametrosquadra] and flagsquadra=true) or  (nominativi.squadra<>[parametrosquadra] and flagsquadra=false))

    nel primo caso vedresti la schiap (squadra=schiap)

    nel secondo caso vedresti tutte tranne schiap (squadra<>schiap)

Devi accedere o registrarti per scrivere nel forum
14 risposte