Sto cercando un modo per filtrare le righe da un SELECT
di una tabella in base a determinati valori nelle righe di un'altra tabella.rimozione di righe da un SELECT in base a colonne in un'altra tabella
Sto sperimentando la seguente struttura di esempio. Ho una tabella dei contenuti dei post del blog (una riga per post del blog) e un'altra tabella dei metadati sui post (una riga per coppia chiave-valore; ogni riga con una colonna che la associa a un post del blog; post sul blog). Voglio tirare una riga di posts
solo se non ci sono righe in metadata
dove metadata.pid=posts.pid AND metadata.k='optout'
. Cioè, per la struttura di esempio qui sotto, voglio solo recuperare la riga posts.id=1
.
(sulla base di quello che ho provato) JOIN
s non finiscono di rimuovere i posti che hanno alcuni metadati dove metadata.k='optout'
, perché l'altra fila di metadati per quel pid
significa che rende nei risultati.
mysql> select * from posts;
+-----+-------+--------------+
| pid | title | content |
+-----+-------+--------------+
| 1 | Foo | Some content |
| 2 | Bar | More content |
| 3 | Baz | Something |
+-----+-------+--------------+
3 rows in set (0.00 sec)
mysql> select * from metadata;
+------+-----+--------+-----------+
| mdid | pid | k | v |
+------+-----+--------+-----------+
| 1 | 1 | date | yesterday |
| 2 | 1 | thumb | img.jpg |
| 3 | 2 | date | today |
| 4 | 2 | optout | true |
| 5 | 3 | date | tomorrow |
| 6 | 3 | optout | true |
+------+-----+--------+-----------+
6 rows in set (0.00 sec)
Una subquery mi può dare l'inverso di ciò che voglio:
mysql> select posts.* from posts where pid = any (select pid from metadata where k = 'optout');
+-----+-------+--------------+
| pid | title | content |
+-----+-------+--------------+
| 2 | Bar | More content |
| 3 | Baz | Something |
+-----+-------+--------------+
2 rows in set (0.00 sec)
... ma utilizzando pid != any (...)
mi dà tutti e 3 le righe di messaggi, causare ogni singolo pid
ha una fila di metadati dove k!='optout'
.
Quindi fammi vedere se ottengo questo ... per un posto con optout, la subquery corrisponde una fila di metadati, in modo che il metadata.mdid non è nullo, così non viene selezionato. Ma un post senza optout, la sottoquery non corrisponde a una riga, quindi il lato destro viene riempito con valori null, quindi la clausola where è true. – alxndr
Ho aggiunto un'altra sezione alla risposta relativa a come funziona il join, che dovrebbe chiarire qualsiasi area grigia con esso. Spero possa aiutare! – futureal