Estoy buscando una manera de filtrar las filas de un SELECT
de una tabla basada en ciertos valores en filas de otra tabla.eliminando filas de un SELECT basado en columnas en una tabla diferente
Estoy experimentando con la siguiente estructura de ejemplo. Tengo una tabla de contenido de publicación de blog (una fila por publicación de blog) y otra tabla de metadatos sobre las publicaciones (una fila por par de clave-valor; cada fila con una columna que la asocia con una publicación de blog; muchas filas por entrada en el blog). Quiero sacar una fila de posts
solo si no hay filas en metadata
donde metadata.pid=posts.pid AND metadata.k='optout'
. Es decir, para la siguiente estructura de ejemplo, solo quiero recuperar la fila posts.id=1
.
(Basado en lo que he tratado) JOIN
s no terminan quitando los puestos que tienen algunos metadatos donde metadata.k='optout'
, porque la otra fila de metadatos para que pid
significa que lo hace en los resultados.
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 subconsulta me puede dar la inversa de lo que quiero:
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)
... pero utilizando pid != any (...)
me da todos los 3 de las filas de mensajes, hacer que todos y cada uno pid
tiene una fila de metadatos donde k!='optout'
.
Así que vamos a ver si me sale esto ... para un post con optout, la subconsulta coincide con una fila de metadatos, por lo que el metadata.mdid no es nulo, por lo no se selecciona. Pero una publicación sin optout, la subconsulta no coincide con una fila, por lo que el lado derecho se rellena con nulos, por lo que la cláusula where es verdadera. – alxndr
He agregado otra sección a la respuesta relacionada con el funcionamiento de la unión, que debería borrar cualquier área gris con ella. ¡Espero que ayude! – futureal