Clausola Use Of Exists in SQL

2

Ho appena finito la lezione di Stanford su SQL (del Prof. Jennifer Widom). Tuttavia ho sviluppato una confusione sull'uso della clausola EXISTS . Ho pensato che fosse proprio come una condizione e un'espressione in modo che se fosse vero, la query sopra procederà (molto simile al% booleano% co_de). Quindi avendo un leggero dubbio riguardo a questa domanda:

Passenger = {pid, pname, Age}
Reservation = {pid, class, tid}

e le tabelle vengono popolate con alcuni dati e viene eseguita la seguente query:

SELECT pid 
FROM Reservation 
WHERE class = 'AC' AND EXISTS
     (SELECT * FROM Passenger WHERE age > 65 AND Passenger.pid = Reservation.pid)

Ora la cosa che mi turba è che ho pensato che l'uso di AND è semplicemente che la query principale sopra procede se la sottoquery restituisce qualcosa. Così come la subquery stava restituendo qualcosa, mi aspettavo che la query restituisse tutti i PID in cui EXISTS . Non pensavo che fosse stata eseguita tupla dalla tupla. Quindi, come rimuovere questa confusione?

    
posta user1369975 21.02.2014 - 11:31
fonte

2 risposte

3

In questo particolare scenario, prenderei in considerazione l'utilizzo di un join nella tabella Passenger e una clausola where per filtrare i risultati. Qualcosa di simile al seguente:

SELECT pid 
FROM Reservation 
INNER JOIN Passenger
  ON Passenger.pid = Reservation.pid
WHERE class = 'AC' and age > 65

Per me questa è una versione più chiara ed è più facile capire cosa sta effettivamente facendo la query.

L'esistente funziona su tutte le righe in Reservation e controlla se soddisfano la query esistente. Per me questo sembra confuso e può essere più veloce unirsi direttamente sul tavolo usando gli id e filtrando dove necessario.

    
risposta data 21.02.2014 - 12:27
fonte
1

Poiché fa riferimento a un oggetto nella query esterna ( Reservation ), la sottoquery è una correlata subquery . Come si dice in quell'articolo di Wikipedia,

The subquery is evaluated once for each row processed by the outer query

Se la sottoquery non fosse correlata, il tuo ragionamento sarebbe corretto. Ad esempio, ipoteticamente,

SELECT pid 
FROM Reservation 
WHERE class = 'AC' AND EXISTS
     (SELECT * FROM Passenger WHERE age > 65)

, a condizione che ci fosse almeno un passeggero sopra i 65 anni, restituisci tutti Reservation s con class='AC' .

    
risposta data 21.02.2014 - 12:38
fonte

Leggi altre domande sui tag