Como escrever uma consulta retornar registros não escolhido
Pergunta
Eu escrevi uma aplicação de testes psicológicos, em que o usuário é apresentado com uma lista de palavras, e ele / ela tem que escolher palavras dez que muito descrever a si mesmo, em seguida, escolher palavras que parcialmente descrever a si mesmo, e palavras que não descrevem a si mesmo. O próprio aplicativo funciona bem, mas eu estava interessado em explorar as possibilidades de meta-dados: quais as palavras foram mais freqüentemente escolhida na primeira categoria, e que palavras nunca foram escolhidos na primeira categoria. A primeira consulta não era um problema, mas o segundo (que palavras nunca foram escolhidos) me deixa perplexo.
A estrutura da tabela é a seguinte:
table words: id, name
table choices: pid (person id), wid (word id), class (value between 1-6)
Provavelmente, a resposta envolve uma esquerda entre palavras e escolhas, mas tem que haver uma declaração modificando - onde choices.class = 1 - e isso está me causando problemas. Escrever algo como
select words.name
from words left join choices
on words.id = choices.wid
where choices.class = 1
and choices.pid = null
faz com que o gerenciador de banco de dados para ir em uma longa viagem para lugar nenhum. Estou usando o Delphi 7 e Firebird 1.5.
TIA, No'am
Solução
Talvez este seja um pouco mais 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)
Outras dicas
Algo como isso deve fazer o truque:
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
Certifique-se de que você tem um índice em choices (class, wid)
.