Aiuto per query dove il WHERE è un'altra query

di il
38 risposte

38 Risposte - Pagina 2

  • Re: Aiuto per query dove il WHERE è un'altra query

    Comunque, ritornando al discorso dei filtri.
    Questo è un esempio di filtro creato tramite una macro, che la puoi far attivare al caricamento della query, con un pulsante o con quello che più ti aggrada.

    filtro.jpg
    filtro.jpg

  • Re: Aiuto per query dove il WHERE è un'altra query

    fratac ha scritto:


    NON MODIFICARE LA STRUTTURA O LE RELAZIONI, altrimenti potresti corrompere per sempre il database.
    Se fino ad ora ha "Funzionato" bisogna metterci delle pezze.
    Per me deve essere una relazione molti a molti, visto che lo stesso esame può essere ripetuto infinite volte con infiniti voti.

    ora tu hai un voto collegato ad infiniti corsi.
    Forse mi sbaglio ma secondo me ora tu hai.

    I numeri tra la parentesi indicato un ipotetico numero ID, che insieme creano una superchiave per ricavare il valore voto(valore atomico)

    Primo esame
    IDVotiAllievi(1)-- IDAllievoCorsi(1) Voto 17 (valore atomico): Bocciato
    ripete l'esame, avrai di nuovo.
    IDVotiAllievi(1)-- IDAllievoCorsi(1) Voto 30 (valore atomico): Promosso.

    Considerando che la relazione tra votiallievi e allievicorsi è uno a molti con join sinistro (e quindi ricavi tutti i corsi, ma solo i voti allievi che sono uguali) se non mi sono sbagliato nel ragionamento, hai una super chiave identica per due voti diversi.

    Fino a quando lo stato è bocciato o promosso il problema non sorge.

    Quando invece ti ritrovi con due voti dello stesso studente sullo stesso corso, ti ritrovi nella condizione di avere la stessa chiave ed in teoria, la query riporta solo il primo valore che trova. Che è bocciato.

    Quindi non è che il database funziona bene. E' la prima volta che ti sei accorto dell'errore.

    Quindi, quale era la domanda iniziale che hai posto?
    Il database funziona bene da anni, sicuramente per ogni funzione che svolge esistevano varie soluzioni e sicuramente ci saranno soluzioni migliori di quelle che ho adottato io, ma questo è un altro discorso.
    Adesso mi è stato chiesto di implementare una nuova funzione, ovvero creare una lista di allievi che hanno delle pendenze (assenze o bocciature) su una determinata materia.

    Purtroppo spiegare in poche righe un database abbastanza complesso non è semplice e alcune affermazioni che fai sono frutto, giustamente, della non conoscenza di tutta la struttura; infatti, ogni esame è univoco:
    es. se io oggi vengo bocciato alla prima sessione dell'esame di storia (IDEsame 1), il mese prossimo dovrò ripetere l'esame di storia, ma sarà un esame diverso dal primo, avrà infatti un'altra data, sarà una seconsa sessione e non prima e ci parteciperanno altre persone (quelle bocciate in prima sessione) e quindi quell'esame avrà la stessa chiave esterna relativa alla materia (storia) ma una chiave primaria diversa (IDEsame 2).

    Volendo ragionare per cicli, dovrei fare un "for" per ogni idallievo e ogni idcurricula (materia) e prendere chi ha un voto inferiore a 18 o è assente.
    Non so se così è più chiaro.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Nel frattempo ho rivisto le relazioni tra le tabelle modificando alcune uno-a-molti in relazioni uno-a-uno ed effettivamente i record che ottengo sono sempre gli stessi, quindi ho semplificato la selezione come diceva qualcuno:
    1.PNG
    1.PNG

    SELECT AllieviAnagrafica.Cognome, AllieviAnagrafica.Nome, Corsi.Corso, Discipline.Disciplina, SessioniEsami.SessioneEsame, Esami.DataEsame, Voti.Voto, VotiAllievi.Assente
    FROM ((Corsi INNER JOIN ((Esami INNER JOIN ((((VotiAllievi LEFT JOIN Voti ON VotiAllievi.IDVoto = Voti.IDVoto) INNER JOIN AllieviCorsi ON VotiAllievi.IDAllievoCorso = AllieviCorsi.IDAllievoCorso) LEFT JOIN AllieviAnagrafica ON AllieviCorsi.IDAllievo = AllieviAnagrafica.IDAllievo) INNER JOIN EsamiVerbali ON VotiAllievi.IDEsameVerbale = EsamiVerbali.IDEsameVerbale) ON Esami.IDEsame = EsamiVerbali.IDEsame) INNER JOIN Curricula ON Esami.IDCurricula = Curricula.IDCurricula) ON Corsi.IDCorso = Curricula.IDCorso) INNER JOIN Discipline ON Curricula.IDDisciplina = Discipline.IDDisciplina) INNER JOIN SessioniEsami ON Esami.IDSessioneEsame = SessioniEsami.IDSessioneEsame
    WHERE (((Voti.Voto)<18) AND ((AllieviCorsi.Transitato)=False) AND ((AllieviCorsi.Dimissionario)=False)) OR (((VotiAllievi.Assente)=True) AND ((AllieviCorsi.Transitato)=False) AND ((AllieviCorsi.Dimissionario)=False))
    

    Con questa selezione il database mi fa vedere tutti gli allievi che hanno avuto una bocciatura o assenza senza tenere conto se per la stessa disciplina hanno un altro voto sufficiente.

    Adesso, secondo me, dovrei aggiungere dei filtri o dei criteri sui campi evidenziati in modo da escludere i record relativi allo stesso allievo che ha già sostenuto e superato un secondo esame (IDesame diverso) della stessa materia (IDDisciplina) uguale.
  • Re: Aiuto per query dove il WHERE è un'altra query

    fratac ha scritto:


    Comunque, ritornando al discorso dei filtri.
    Questo è un esempio di filtro creato tramite una macro, che la puoi far attivare al caricamento della query, con un pulsante o con quello che più ti aggrada.

    filtro.jpg
    ma perdonami, perchè usare una macro se posso usare i criteri sulla query stessa?
    Alla fine come non so cosa scrivere sul criterio della query non saprei cosa scrivere sul filtro.

    Cioè logicamente so cosa fare, ma non lo tradurre in sql.
  • Re: Aiuto per query dove il WHERE è un'altra query

    In "italiano" la selezione sarebbe:
    "seleziona
    IDAllievo, IDDisciplina, Cognome, Nome, Corso, Disciplina, Sessione Esame, Voto e Assenza
    da
    tabella VotiAllievi collegata alle altre tabelle come in foto
    dove
    il voto più basso per ogni IDdisciplina è <18 o assenza = -1"

    Bisognerebbe tradurla su Access.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Non puoi usare il valore del voto come condizione. Perché se uno studente prende 28 e tii rifiuta il voto, comunque non ha passato l esame ed il sistema te lo considera promosso.
  • Re: Aiuto per query dove il WHERE è un'altra query

    fratac ha scritto:


    Non puoi usare il valore del voto come condizione. Perché se uno studente prende 28 e tii rifiuta il voto, comunque non ha passato l esame ed il sistema te lo considera promosso.
    Questo problema non si pone per fortuna.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Come non si pone?
    Non si è mai presentata la fattispecie, oppure la query te lo fa vedere nei risultati dei bocciati anche se il voto è maggiore di 17?
    Perché in teoria se hai il problema con i promossi in seconda sessione, dovresti abere anche il problema inverso.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Non si pone perchè se l'allievo non può rifiutare il voto e anche se fosse non verrebbe trascritto.
    Non complichiamo le cose con casistiche che non si verificheranno mai.
    Questo database è nato per una realtà universitaria particolare.
    Ci sono eccezioni che nelle università normali non esistono come allievi non diplomati che seguono come uditori etc...

    La questione è complicata... ma alla fine la mia esigenza è quella postata nell'ultimo post:
    "seleziona
    IDAllievo, IDDisciplina, Cognome, Nome, Corso, Disciplina, Sessione Esame, Voto e Assenza
    da
    tabella VotiAllievi collegata alle altre tabelle come in foto
    dove
    il voto più basso per ogni IDdisciplina è <18 o assenza = -1"
  • Re: Aiuto per query dove il WHERE è un'altra query

    Il problema è che non puoi usare il voto per determinare la promozione, perché non è univoco. Anche applicando un filtro al risultato della query, praticamente usando il voto andresti a filtrare anche quelli che non sono stai promossi.
    Quindi devi trovare un campo univoco da poter sfruttare , oppure aggiungere da qualche parte un campo dove immetti promosso o bocciato.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Scusami ma mi vorresti dire che, da una tabella dove io ho caricato tutti i voti di ogni allievo per ogni materia non è possibile fare una selezione andando a prendere gli allievi che non hanno almeno 18 per ogni materia?

    Se io stampo quella tabella, a mano, riesco ad avere il dato che mi serve, perchè con access non potrei?

    Devo fare una sorta di ciclo dove per ogni allievo e ogni materia verifico se ha almeno un 18.
    Mi sembra facile come concetto... poi ovviamente va tradotto in access.
  • Re: Aiuto per query dove il WHERE è un'altra query

    fratac ha scritto:


    Il problema è che non puoi usare il voto per determinare la promozione, perché non è univoco.
    Infatti non devo usare il voto ma il max di voto per esempio.
    "Se il max di voto è <18 o assente = -1 allora..."
  • Re: Aiuto per query dove il WHERE è un'altra query

    Ho capito. Ma se uno studente ha due voti, uno minore ed uno maggiore, rispetta sia il caso di bocciato che di promosso. Quindi verrà visualizzato nella query, sia dei bocciati che dei promossi. Comunque prova a mettere un dcount =1 nella condizione where, in modo che se uno studente ha due record con voto te lo esclude
  • Re: Aiuto per query dove il WHERE è un'altra query

    Non ti seguo...
    Se pippo per la stessa IDDisciplina ha due voti, 16 e 20, il massimo è solo 20 quindi viene escluso perchè la condizione "max di voto < 18" NON viene rispettata.
  • Re: Aiuto per query dove il WHERE è un'altra query

    Il problema non è che non ti seguo io, ma che non ti segue nemmeno il database nel ragionamento che fai.
    Ma se hai due valori, uno che rispetta le condizioni e l'altro no, quando fai la query te lo ritrovi nei risultati. Solo che non è il risultato giusto per determinare lo stato dello studente.
    Tu chiedi alla query, trovami tutti i record con voto minore di 18 e lei te li trova tutti.
    Quindi, per come è strutturato il database hai due possibilità. O aggiungi un altro campo alle tabelle, dove indichi lo stato dello studente, e usi quello come criterio, oppure dici alla query che se trova due o piu voti per lo studente, deve escluderlo dai risultati dei bocciati. Praticamente quello che fai mentalmente oppure prova un betwen tra 18 e 30. Ma tanto avrai sempre lo stesso problema.
Devi accedere o registrarti per scrivere nel forum
38 risposte