Cómo escribir una consulta que devuelve registros no seleccionados
Pregunta
He escrito una aplicación de prueba psicológica, en la que al usuario se le presenta una lista de palabras, y él / ella tiene que elegir diez palabras que mucho se describe a sí mismo, luego elegir palabras que parcialmente describirse a sí mismo, y las palabras que no se describen a sí mismo. La aplicación en sí funciona bien, pero me interesó explorar las posibilidades de metadatos: qué palabras se han elegido con mayor frecuencia en la primera categoría y qué palabras nunca se han elegido en la primera categoría. La primera consulta no fue un problema, pero la segunda (cuyas palabras nunca se han elegido) me deja perplejo.
La estructura de la tabla es la siguiente:
table words: id, name
table choices: pid (person id), wid (word id), class (value between 1-6)
Presumiblemente, la respuesta involucra una combinación a la izquierda entre palabras y elecciones, pero tiene que haber una declaración de modificación, donde choices.class = 1, y esto me está causando problemas. Escribiendo algo como
select words.name
from words left join choices
on words.id = choices.wid
where choices.class = 1
and choices.pid = null
hace que el administrador de la base de datos vaya en un viaje largo a ninguna parte. Estoy usando Delphi 7 y Firebird 1.5.
TIA, No'am
Solución
Tal vez esto sea un poco más rápido:
SELECT w.name
FROM words w
WHERE NOT EXISTS
(SELECT 1
FROM choices c
WHERE c.class = 1 and c.wid = w.id)
Otros consejos
Algo así debería hacer el truco:
SELECT name
FROM words
WHERE id NOT IN
(SELECT DISTINCT wid -- DISTINCT is actually redundant
FROM choices
WHERE class == 1)
SELECT words.name
FROM
words
LEFT JOIN choices ON words.id = choices.wid AND choices.class = 1
WHERE choices.pid IS NULL
Asegúrese de tener un índice en las opciones (clase, wid)
.