2009-07-28 12 views
6

Aggiornamento da richiesta @Cesar. Spero di aver capito cosa vuoi, in caso contrario, per favore, ripristina. Quassnoi.Valutazione di multipli 'IN' Espressioni in clausole 'WHERE' in mysql

Se faccio un SQL query come questa: SELECT * FROM TABLE_NAME WHERE b IN (2, 7) AND c IN (3, 9), posso supporre che MySQL selezionerà solo le coppie di elementi con lo stesso numero in ciascuna lista?

Cioè, (2, 3), (7, 9), ...?

Per esempio, supponiamo di avere una tabella come questa:

 
+----------+----------+----------+ 
| PK |  b |  c | 
+----------+----------+----------+ 
|  1 |  2 |  3 | 
+----------+----------+----------+ 
|  2 |  5 |  4 | 
+----------+----------+----------+ 
|  3 |  7 |  9 | 
+----------+----------+----------+ 
|  4 |  7 |  4 | 
+----------+----------+----------+ 
|  5 |  2 |  9 | 
+----------+----------+----------+ 

È corretto presumere che i solo righe restituite sono 1 e 3 (e non 5)?

+0

è consigliabile modificare "c IN (4,4)" nel proprio esempio per chiarimenti. – palindrom

+0

@Quassnoi: Sì, mi hai capito perfettamente, grazie! – Cesar

risposta

14
SELECT * FROM TABLE_NAME WHERE b IN(5,7) AND c IN(4,4) 

Questa query restituirà le righe, dove b è o 5 o 7, e c è 4.

Cosa intendi per "valutazione a coppie?"

Aggiornamento:

io aggiungo di più una riga al campione:

+----------+----------+----------+ 
| PK |  b |  c | 
+----------+----------+----------+ 
|  1 |  2 |  3 | 
+----------+----------+----------+ 
|  2 |  5 |  4 | 
+----------+----------+----------+ 
|  3 |  7 |  9 | 
+----------+----------+----------+ 
|  4 |  7 |  4 | 
+----------+----------+----------+ 
|  5 |  2 |  9 | 
+----------+----------+----------+ 

Se si desidera far corrispondere l'intero set, è possibile utilizzare la seguente sintassi:

SELECT * 
FROM table_name 
WHERE (b, c) IN ((2, 3), (7, 9)) 

Ciò significa: "restituire tutte le righe dove b è 2 e c è 3, allo stesso tempo, o b è 7 e с è 9 allo stesso tempo."

Nell'esempio di cui sopra, questa query restituirà le righe 1 e 3

Ma se si riscrivere questa query il contrario intorno, in questo modo:

SELECT * 
FROM table_name 
WHERE b IN (2, 7) 
     AND c IN (3, 9) 

, questo significa "tornare tutte le righe in cui è o b2 o 7, e c o è 3 o 9).

Ciò restituirà righe 1, 3 e 5, poiché fila 5 soddisfano le condizioni per la seconda query ma non per la prima.

+0

Sì, questo è quello che sto cercando di fare (l'intero set cosa), solo che non sono un parlante inglese e credo di non essere stato chiaro Se qualcuno potesse modificare la domanda per riflettere cosa sto cercando, per favore sentiti libero di farlo. – Cesar

+0

(b, c) IN ((2, 3), (7, 9)) non funziona in mariadb – DevWL

+0

@DevWL: sì lo fa – Quassnoi

5

Il ritorno di righe 2 & 4 è corretta, anche se la scelta di (4,4) può rendere un po 'più confuso, come è ridondante. L'AND significa che la riga deve soddisfare entrambe le condizioni affinché sia ​​vero. Se la query avesse WHERE b IN(5,7) AND c IN(4,9), si otterrebbero le righe 2, 3 e 4 restituite.

Se ci pensi in coppia, devi avere tutte le combinazioni. ad esempio, b IN(5,7) AND c IN(4,9) darebbe (5,4), (5,9), (7,4) e (7,9) come possibili combinazioni che funzionerebbero, e NON solo (5,4) e (7,9)

0

Sì, credo che tu abbia ragione.

In effetti, "IN" può essere considerato una scorciatoia per (b = 5 O b = 7). Questo NON è il modo in cui funziona "sotto il cofano", ma è un modo semplice per pensarci.

Per tabelle di grandi dimensioni, più clausole 'IN' causeranno problemi di prestazioni.

EDIT:

È possibile che questo manifesto è corretta, C (4, 4) è inutile. Si potrebbe facilmente dire 'AND c = 4'.

Se si converte le clausole nei loro equivalenti logiche, si vede il motivo per cui:

SELECT * FROM tabella WHERE (b = 5 OR b = 7) e (C = 4 oppure c = 4)

+2

È corretto che la sua query restituirà le righe 2 e 4 ma non per il motivo che pensa. – Rafe

+0

Ah, ho appena capito cosa intendeva per "valutazione in coppia" e ho chiarito la mia risposta. – Jeff

4

È possibile valutare ogni condizione in ordine, potrebbe darvi un'idea migliore di ciò che sta accadendo qui. La query afferma che tutti i valori dovrebbero essere selezionati dove b è o 5 o 7 e c è 4, quindi cerchiamo di ridurre la tabella utilizzando prima condizione (b IN (5,7)):

+----------+----------+----------+ 
| PK |  b |  c | 
+----------+----------+----------+ 
|  1 |  2 |  3 | < No match 
+----------+----------+----------+ 
|  2 |  5 |  4 | < Match 
+----------+----------+----------+ 
|  3 |  7 |  9 | < Match 
+----------+----------+----------+ 
|  4 |  7 |  4 | < Match 
+----------+----------+----------+ 

Ora, cerchiamo di valutare la condizione successiva, entrambi devono essere vero in ordine per una riga da selezionare (c IN (4,4), HICH è essenzialmente lo stesso come c = 4):

+----------+----------+----------+ 
| PK |  b |  c | 
+----------+----------+----------+ 
|  2 |  5 |  4 | < Match 
+----------+----------+----------+ 
|  3 |  7 |  9 | < No match 
+----------+----------+----------+ 
|  4 |  7 |  4 | < Match 
+----------+----------+----------+ 

Tutto il resto è valida:

+----------+----------+----------+ 
| PK |  b |  c | 
+----------+----------+----------+ 
|  2 |  5 |  4 | 
+----------+----------+----------+ 
|  4 |  7 |  4 | 
+----------+----------+----------+ 
1

L'esempio non illustra esattamente la domanda, ma le clausole multiple IN non sono correlate l'una all'altra, ; vengono valutati in sequenza come qualsiasi altra clausola WHERE.

Pertanto, la seguente query

SELECT * FROM FOO WHERE b IN(5,7) AND c IN(4,8) 

corrisponderà una delle seguenti operazioni:

b c 
---- 
5 4 
5 8 
7 4 
7 8

IN può essere considerata un'abbreviazione per confronti o-separati.Questo significa che la query precedente può anche essere scritta come (la meccanica sono leggermente diversi, ma il concetto è lo stesso):

SELECT * FROM FOO WHERE (b = 5 OR b = 7) AND (c = 4 OR c = 8) 

Quindi, nel tuo esempio, sì, le uniche righe restituite sono 2 e 4. Ma non è abbastanza per la ragione che supponi.

Problemi correlati