Newsgroup: it.comp.www.php
Titolo: query su relazione 1 a n

ho una relazione 1:n (per esempio studenti - esami: uno studente da più
esami)
studenti (idS, nome)
esami (idE, idS_FK, materia, voto, data)
supponiamo che lo studente s1 abbia dato gli esami e1, e2, e3
supponiamo che lo studente s2 abbia dato gli esami e1, e2
supponiamo che lo studente s3 abbia dato gli esami e1
devo fare una query per sapere chi ha superato gli esami e1, e2 (che
quindi mi dovrebbe restituire gli studenti s1 e s2)
NON CI RIESCO: perchè scrivendo:
SELECT studenti.nome, esami.materia
FROM studenti INNER JOIN esami ON 
studenti.id
 = esami.idS_FK
WHERE (((esami.materia)="e1" And (esami.materia)="e2"));
non restuisce nulla (giustamente) dato che i 2 esami sono su record
DIVERSI della tabella esami e quindi la condizione AND non è mai vera
Problema: come potrei fare? E' il database progettato male?
P.S.: utilizzo MySql
grazie
ciao
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

vedoNero ha scritto:

puoi provare a fare una select un pò complessa
select a.nome, a.materia from 
(
SELECT studenti.nome, esami.materia
 FROM studenti , esami 
  where 
studenti.id
 = esami.idS_FK
and  (((esami.materia)="e1"
-- 
Postato da Virgilio Newsgroup: lo usi da web ma con le funzioni del newsreader 
http://newsgroup.virgilio.it
Gerarchie it, italia, it-alt, tin, it.binari. Unico!

Bramante ha scritto:

Ho sbagliato nel'inviare
comuqnue la soluzione c'è (se aspetti appena finisco una cosa te
la indico)
comunque l'idea sarebbe quella di normalizzare il tutto
gli esami sono un entità FINITA e ben definita, quindi sarebbe
preferibile riportare il tutto sotto forma di 
ids, nome , e1,e2,e3,e4 ecc..
ed eventualmente assegnare un flag se lo studente lo ha passato ,
sostenuto o bocciato del tipo
1 sostenuto, 2 passato, 3 bocciato ecc
esempio
ids, nome       , e1 ,e2 ,e3 ,e4
----------------------------------
1  , mario rosii, 1  ,2  ,1  ,3
(non so se si leggera bene)
questo lo si puo fare anche con una relazione n - n come nel tuo
caso (tante che n studenti fanno n-esami) 
1 studente n-esami
1 esami n-studenti
Ciao


vedoNero ha scritto:

Rieccomi
select a.ids, a.nome from
(select ids, nome from studenti, esami
 where studenti.ids = esami.ids
   and esami.materia = 'e1') a,
(select ids, nome from studenti, esami
 where studenti.ids = esami.ids
   and esami.materia = 'e2') b
where a.ids = b.ids
prima soluzione: seleziono solo gli studenti che hanno l'esame
"e1" e poi solo gli studenti che hanno l'esame "e2"
e faccio la join per vedere solo quelli che sono in comune
-----------------------
select ids, count(*) from (
select distinct ids, nome from studenti , esami
where studenti.ids = esami.ids
   and esami.materia = 'e1'
union
select distinct ids, nome from studenti , esami
where studenti.ids = esami.ids
   and esami.materia = 'e2')
group by ids, having count(*) > 1
seconda soluzione : selezione gli studenti che hanno l'esame "e1"
e gli unisco agli studenti che hanno l'esame "e2"
li conto e li raggruppo per ids, quelli che hanno un conteggio
maggiore di 1 significa che hanno sostenuto entrambi gli esami.


grazie davvero
