Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [sql] selezione record senza relazioni

    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...
    http://www.easymemo.it - vCard ed agenda

  2. #2
    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!
    "Le uniche cose che sbagli sono quelle che non provi a fare."
    Atipica

  3. #3
    Si, ho a disposizione le subquery, uso access, ma potresti farmi un esempio un po più pratico?

    Grazie
    http://www.easymemo.it - vCard ed agenda

  4. #4
    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!
    "Le uniche cose che sbagli sono quelle che non provi a fare."
    Atipica

  5. #5
    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

    codice:
    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

    codice:
    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.

  6. #6

    sorry

    """"
    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)
    il tempo si fa i fatti suoi

  7. #7
    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

    codice:
    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

    codice:
    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.

    codice:
    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)

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.