PDA

Visualizza la versione completa : [sql] selezione record senza relazioni


zed79
17-02-2004, 14:15
Ciao,

Date due tabelle A e B relazionate uno a molti, vorrei selezionare tutti i record della tabella A che non hanno nessuna relazione con record della tabella B.

Ringrazio chiunque mi dia una mano...

Shores
17-02-2004, 14:20
Se hai a disposizione le subquery puoi procedere così:

Prima crei una query che conti i record collegati nella tabella secondaria:

select count(id) from secondatabella group by idesterno;

Poi fai una join con la prima tabella e prendi quelli che hanno 0 record collegati.

Ciao!

zed79
17-02-2004, 14:23
Si, ho a disposizione le subquery, uso access, ma potresti farmi un esempio un po più pratico?

Grazie

Shores
17-02-2004, 14:31
Più pratico?

primatabella:
id
descrizione

Secondatabella:
Id
Descrizione
IdPrimaTabella


Prima query:

SELECT IdPrimaTabella, COUNT(Id) as numero FROM secondatabella group by IdPrimaTabella

la salvi con nome pippo.

SEconda query:

SELECT * from primatabella left join pippo on primatabella.id=pippo.idprimatabella where numero=''

Ed ecco fatto, direi...

Può darsi che tu debba giocare un po' con la where della seconda query...

Ciao!

internet
17-02-2004, 16:29
Originariamente inviato da zed79
Si, ho a disposizione le subquery, uso access, ma potresti farmi un esempio un po più pratico?

Grazie

Visto che usi Access questa query va bene.

Esempio

Ordine(id, descrizione)
Dettaglio(id, idOrdine, descrizione)

Ordine <--1 a molti---> Dettaglio



SELECT Ordine.descrizione
FROM Ordine
WHERE Ordine.id NOT IN
(SELECT DISTINCT Dettaglio.idOrdine FROM Dettaglio)



p.s.
ho messo i nomi delle tabelle per indicare i campi a cui si riferiscono, ma in questo caso non sono necessari, visto che non ci possono essere ambiguità.

quindi in questo caso specifico anche questo va bene



SELECT descrizione
FROM Ordine
WHERE id NOT IN
(SELECT DISTINCT idOrdine FROM Dettaglio)


La stessa query si potrebbe fare con EXCEPT (ANSI SQL92) che corrisponde all'operatore insiemistico differenza utilizzato nell'algebra relazionale, solo che Access e MySQL non lo supportano.

JackBabylon
25-02-2004, 17:09
""""
SELECT descrizione
FROM Ordine
WHERE id NOT IN
(SELECT DISTINCT idOrdine FROM Dettaglio)
""""

se le tabelle sono un po grosse ti conviene fare cosi (almeno in oracle è molto più veloce)

select descrizione
from ordine ord
where not exists (select 1 from dettaglio det where det.id = ord.id)

internet
25-02-2004, 21:11
Ho fatto dei test su PostgreSQL e effettivamente usando DISTINCT, crea un casino (pensavo erroneamente fosse un vantaggio, visto che al secondo scan avrebbe fatto meno lavoro e invece



test=# explain SELECT descrizione
test-# FROM Ordine
test-# WHERE id NOT IN
test-# (SELECT DISTINCT idOrdine FROM Dettaglio);
NOTICE: QUERY PLAN:

Seq Scan on ordine (cost=0.00..857.02 rows=2 width=5)
SubPlan
-> Materialize (cost=285.33..285.33 rows=100 width=4)
-> Unique (cost=282.83..285.33 rows=100 width=4)
-> Sort (cost=282.83..282.83 rows=1000 width=4)
-> Seq Scan on dettaglio (cost=0.00..233.00 rows=1000 width=4)


mentre togliendo DISTINCT



test=# explain SELECT descrizione
test-# FROM Ordine
test-# WHERE id NOT IN
test-# (SELECT idOrdine FROM Dettaglio);
NOTICE: QUERY PLAN:

Seq Scan on ordine (cost=0.00..350.54 rows=2 width=5)
SubPlan
-> Seq Scan on dettaglio (cost=0.00..233.00 rows=1000 width=4)


comunque la soluzione di JackBabylon è leggermente più veloce.



test=# explain SELECT descrizione
test-# FROM ordine
test-# WHERE not exists (select 1 from dettaglio where idOrdine = ordine.id);
NOTICE: QUERY PLAN:

Seq Scan on ordine (cost=0.00..1.74 rows=2 width=5)
SubPlan
-> Seq Scan on dettaglio (cost=0.00..235.50 rows=1000 width=0)

Loading