2012-09-22 11 views
5

Esiste un equivalente di algebra relazionale dell'espressione SQL NOT IN?Equivalente algebra relazionale di SQL "NOT IN"

Per esempio se ho la relazione:

A1 | A2 
---------- 
x | y 
a | b 
y | x 

voglio rimuovere tutte le tuple nella relazione per la quale A1 è in A2. In SQL Potrei ricerca:

SELECT 
    * 
FROM 
    R 
WHERE 
    R.A1 NOT IN 
     (
     SELECT 
      A2 
     FROM 
      R 
     ) 
/

Ciò che veramente mi stumping è come sottoquery all'interno dell'operatore selezione algebra relazionale, è questo possibile ?:

σ alcuni subquery qui R

risposta

6

In Algebra relazionale, puoi farlo usando un prodotto cartesiano. Qualcosa di simile:

R - ρ A1, A2 A11, A21 A11 = A22 A11, A21 (R) x ρ A12, A22 (R))))

  • rinomina le colonne di R, fe da A1 ad A11 (a sinistra) e l'A12 (mano destra)
  • prendere il prodotto trasversale della R con colonne rinominati
  • selezionare le righe in cui A11 uguale a22
  • progetto fuori A12 e A22 e mantenere A11 e A21
  • rinominare in A1 e A2

che ti dà le righe che sono stati abbinati. Sottrai questo da R per trovare le righe che non corrispondono.

+1

si può spiegare come funziona ... e magari ampliare i puntini puntini di sospensione. Ho difficoltà a capire il risultato del prodotto incrociato, ci sono solo due campi in R, quindi come si può inserire l'operatore pi con più di due argomenti? – jsj

+0

Se ci sono solo due colonne è possibile omettere i punti di ellissi. La risposta ha utilizzato anche PI dove avrebbe dovuto usare RHO, non è sicuro se fosse nella modifica o nella risposta originale. – Andomar

+0

@Andomar: sto riscontrando anche problemi nella domanda di Algebra relazionale. Ho postato la mia domanda [qui] (http://stackoverflow.com/questions/18997845/how-to-convert-sql-to-relational-algebra-in-case-of-sql-joins). Puoi per favore aiutarmi qui? Grazie. –

2

La domanda di apertura ci sta inviando il pensiero sbagliato. Dovrebbe essere:

Esiste un equivalente di algebra relazionale dell'espressione SQL R WHERE ... [NOT] IN S?

(Cioè, la risposta è un po 'di funzionamento tra due relazioni, non una sorta di filtro.)

La risposta è sì, è (Natural) JOIN alias l'operatore papillon .

Per capire perché, innanzitutto riordinare la soluzione SQL fornita. Come mostrato, sta cercando l'attributo A1 NOT IN una relazione con il singolo attributo A2. Questo è davvero un errore nel nome degli attributi. SQL consente anche NOT all'interno della condizione where. Questo SQL rende la struttura logica più chiara:

SELECT * FROM R 
WHERE NOT (A1 IN (SELECT A2 AS A1 FROM R)) 

Ora possiamo vedere una proiezione e una rinomina. (I dintorni NOT possiamo implementare come impostato MINUS, come da prima risposta.) Quindi la RA è equivalente:

R - (R ⋈ ρ A1/A2 A2(R)))

Per interesse, l'Tutorial D è:

R MINUS (R JOIN (R {A2} RENAME A2 AS A1)) 

Nel modo in cui la questione è messo, non c'è una sbornia dal pensiero SQL. Lo WHERE di SQL ti costringe a "modalità" a livello di riga. Questa è la regola 7 di contra Codd che richiede operatori "set-at-a-time".

In generale, di SQL WHERE e RA di σ con i loro filtri a livello di riga possono essere attuati in modo più efficace sintesi (naturale) JOIN con logica set-at-a-time. (Per esempio, questo è ciò che Data & Darwen fare loro Un algebra.)