Newsgroup: it.comp.lang.visual-basic
Titolo: [QUERY] Risoluzione

E' da ieri che non riesco a risolvere questa query.
Ho 1 tabella ricavata da una query precedentemente fatta dove mi
estrapola l'elnco delle persone con il relativo codice del corso che
hanno fatto; quindi (esempio):
CODICE PERSONA - CODICE CORSO
1		      -  001	
1		      -  002	
1		      -  030	
2		      -  001	
2		      -  004	
3		      -  013
etc.
Come faccio a selezionare SOLO quelle persone che NON hanno fatto per
esempio il corso 001?
Query leggerà record ma mi tirerà fuori lo stesso 1 perchè vedrà si
che il primo record ha CODICE CORSO 001 ma il secondo no.
Mi sono spiegato? Azz... non mi viene in mente proprio niente.
Grazie.
Andrea.	

 esempio il corso 001?
SELECT * FROM tabella WHERE [codice corso]<>'001'


 esempio il corso 001?
Soluzione brutta e lenta:
SELECT DISTINCT PERSONA
FROM TABELLA WHERE NOT PERSONA IN (SELECT PERSONA FROM TABELLA WHERE
CORSO=1)
<x:termoPilucco>

> Mi sono spiegato? Azz... non mi viene in mente proprio niente.
	    CODICE PERSONA - CODICE CORSO
1° record          1	          -       001
2° record          1                     -       002
3° record          2                     -       001 
4° record          3                     -       003
Ora trovami CODICE PERSONA che HA CODICE CORSO <> '001'
Per CODICE PERSONA 2 non cè problema MA per CODICE PERSONA 1 sì e me
lo tirerà fuori perchè il secondo record viene selezionato. E invece
il risultato della query dovrebbe selezionare SOLO CODICE PERSONA 3!!!
COME FARE?

 semplice!!!!!!
Guarda che qui, talvolta, ci sono domande fatte da persone che non sanno
neppure accendere il PC, per cui il dubbio sulla competenza di chi chiede
c'č sempre.
<x:termoPilucco>, e non senza ragione.

c'è sempre.
Guarda che qui è un bel pò di tempo che posto/lurko quindi so come
vanno le cose. E cmq non mi interessa se uno dubita ma se uno risponde
tanto PER rispondere ( ...CODICE CORSO<>'001') permetti che io con
tutta calma gli faccia notare che, essendo 2 giorni che mi scervello,
questa strada l'ho già provata?!
Piuttosto apprezzo la tua di risposta che non è così OVVIA.

 SELECT * FROM tabella WHERE [codice corso]<>'001'
no, non credo che intedesse questo.
lui vuole sapere quali *persone* non hanno fatto il corso 001. con quella
query gli ritorna anche la riga 2. cioč il corso 002 seguito perň dalla
persona 1 che ha anche fatto il corso 001.
l'idea potrebbe essere quella di fare una query che restituisca le persone
che hanno fatto il corso 001 e poi una seconda query che restituisca tutte
le persone contenute nella tabella meno quelle trovate dalla prima query. ho
provato ma purtroppo non sono riuscito a fare la seconda query... :-(((
ovviamente sono io che non riesco.
la prima l'ho scritta cosě
SELECT * FROM tabella
WHERE tabella.corso)='001'
la seconda:
SELECT tabella.nome FROM tabella, query
WHERE tabella.nome NOT IN ([query].[nome])
ma mi restituisce sempre tutte le righe.
dove ho sbagliato ?
Marco

 Piuttosto apprezzo la tua di risposta che non è così OVVIA.
Se hai un numero elevato di record ed usi Access può diventare
inutilizzabile.
Forse joinando la tabella con se stessa si può fare qualcosa di meglio.
<x:termoPilucco>

no, non credo che intedesse questo.
Esatto!!! :-)
E' quello che sto tentando di fare anche io con 2 query ma non
riesco.:-(
Cmq grazie.

E' un po' laboriosa ma dovrebbe funzionare...
Dim rs as recordset
set rs=tuaconnessione.execute("SELECT CodicePersona FROM Tabella WHERE
Tabella.Corso = '001'" )
Scorri questo recorset per costruire una stringa di "where" es.:
dim str as string
Do until rs.eof
    if str ="" then
        str = " WHERE "
    end if
    str=str & "CodicePersona <> '" & rs!CodicePersona & "' AND "
    rs.moveNext
Loop
set rs=nothing
if str <> "" then
    str=Mid$(str,0,len(str) - 4)   'tolgo l'ultimo AND che non ci vuole
end if
poi fai una seconda query:
"SELECT * FROM Tabella " & str
E' un po' "grezza", ma cosě al volo non mi viene in mente nient'altro...
            Ciao
                    Zephiross

 COME FARE?
HO CAPITO! NON TI INCAXXARE!
scherzo naturalmente
ciaociao

ecco il testo del post:
ops...non avevo letto bene!
Credo tu debba usare una clausula WHERE IN con un'altra select
all'interno.... ora la metto gių, aspetta
ciaociao


seee...buonanotte a me!! Ci ha giā pensato Termopilucco... :)
ciaociao

 riesco.:-(
La mia query l'hai provata?
Altrimenti, solo per Access,  usa questa:
SELECT persona
FROM TABELLA  group by persona having min(iif(CORSO='001',0,1))=1
<x:termoPilucco>, due giorni?

> La mia query l'hai provata?
io l'ho provata e funziona. ma cosa c'è di sbagliato in quella che ho
postato io ?
in pratica sono le due query anzichè annidate separate. dove ho sbagliato ?
grazie!
Marco

<x:termoPilucco>, due giorni?
....

 sbagliato ?
Tu hai messo il distinct?
Alberto
-- 
"Tina, ta te tňta tinta un tac!"
"Te cat tac i tac, m'tac't un tac?"
"Me ca tac un tac a tč?
Tac'tel te l tň tac, tň!"

 in pratica sono le due query anzichè annidate separate. dove ho sbagliato
?
hai scritto:
SELECT * FROM tabella
WHERE tabella.corso)='001'
Qui  ti serve un solo campo (non usare *)
la seconda query:
SELECT tabella.nome FROM tabella, query
WHERE tabella.nome NOT IN ([query].[nome])
Qui invece hai scritto "FROM tabella, query"
che implica il prodotto cartesiano delle due tabelle/query.
Ti sarebbe bastato  "FROM tabella".
Infine
"WHERE tabella.nome NOT IN ([query].[nome])"
Access non riconosce questa sintassi: alla clausosa la "IN" deve seguire un
insieme di elementi o una query esplicita es: not in (select [query].[nome]
from query)
Tra l'altro insisto nel dire che usare "NOT IN" in Access è da suicidio: le
prestazioni decadono con appena 500 record.
<x:termoPlucco>

 Mi da errore.
Hai sbagliato a convertire i nomi o i tipi del tuo DB: a me funziona
esattamente come l'altra, solo che è velocissima.
<x:termoPilucco>, errore?

<x:termoPilucco>, errore?
Correggo, funziona, ora devo passare come parametro il CODICE CORSO
che non voglio.
Grazie.

> >FROM TABELLA  group by persona having min(iif(CORSO='001',0,1))=1
Sto guardando l'help ma non riesco a capire molto bene:
min(iif(CORSO='001',0,1))=1
cioč viene restituito 0 se CORSO =001  e 1 se CORSO<>001
e mi prende solo quelli con risultato 1 e raggruppandoli per persona
mi evita le ripetizioni, giusto?

 Infine
[snip]
ehm... ok. visto, corretto e spero imparato...
grazie 1000!
Marco

 persona mi evita le ripetizioni, giusto?
"group by persona" : raggruppo i risultati per singola persona (quindi
ottengo le persone distinte).
"having" filtro applicato successivamente al raggruppamento quindi sul
gruppo di record relativi alla persona.
 iif(CORSO='001',0,1))=1 :viene restituito 0 se CORSO ='001'  e 1 se
CORSO<>'001'
min(espressione) : viene preso il valore minimo tra i record definiti da
espressione, ma relativi al singolo regrruppamento.
A parità di persona venogono valutati tutti i campi CORSO se nessun corso è
'001' si ha min(iif(CORSO='001',0,1))=1
<x:termoPilucco> contorto.

 wrote in message
bn827c$t56s2$1...@ID-188026.news.uni-berlin.de...

SELECT DISTINCT PERSONA
 FROM TABELLA a WHERE NOT exists (SELECT PERSONA FROM TABELLA b WHERE
 CORSO=1 and a.PERSONA = b.PERSONA)
Dovrebbe essere più veloce e Standard SQL, sempre che  i campi formino
un'indice :-))
Saluti, Il Sora!!

 un'indice :-))
L'idea non è male: ho testato i tempi delle tre soluzioni uscite finora:
con circa 4000 record, senza indice
Soluzione con "not exists": 37 secondi
Soluzione con "not in":     50 secondi
Soluzione con "having":   <1 secondo
con circa 250.000 record, con indice
Soluzione con "not exists": 9 secondi
Soluzione con "not in":     8 secondi
Soluzione con "having":   2,5 secondi
<x:termoPilucco>, and the winner is... :)

 L'idea non č male: ho testato i tempi delle tre soluzioni uscite
[cut]
Devo riconoscere che quando ho letto la tua idea dell'having col Min e
l'IIF, l'ho trovata molto furba.
In questo modo si fa una sola scansione della tabella, mentre con una
subquery con Not In o Not Exist, comunque da qualche parte c'č un prodotto
cartesiano, che, per quanto possa essere ben indicizzato, non potrą mai
essere efficiente come una singola scansione.
Se anche i numeri ti danno ragione, mi sembra una cosa da segnare.
Ciao
Alberto
-- 
"Tina, ta te tņta tinta un tac!"
"Te cat tac i tac, m'tac't un tac?"
"Me ca tac un tac a tč?
Tac'tel te l tņ tac, tņ!"


Certo..si sapeva già..ma non è Sql Standard.. :))
Buon appetito, Il Sora!!

 Se anche i numeri ti danno ragione, mi sembra una cosa da segnare.
Aspetta a segnare :)
Modificando il tipo del corso da testuale a numerico e supponendo di voler
testare chi non partecipa al corso 132
si può rielaborare in
SELECT persona FROM TABELLA GROUP BY persona HAVING min(abs(CORSO-132))<>0
che è più veloce ed adattabile ai vari dialetti SQL.
<x:termoPilucco>, ok adesso la smetto.