2014-07-14 100 views
-1

我有一个SQL查询,它执行大部分我需要的操作,但我遇到了一个问题。SQL查询来检查值是否在另一个表中不存在

共有3张桌子。 entriesentry_metavotes

我需要在entry_meta表和ID无论是从entriescompetition_id = 420得到一个整行votes不存在,或者它确实存在,但user_id列的值不是1

这里的查询我正在使用:

SELECT entries.* FROM entries 
INNER JOIN entry_meta ON (entries.ID = entry_meta.entry_id) 
WHERE 1=1 
    AND ((entry_meta.meta_key = 'competition_id' AND CAST(entry_meta.meta_value AS CHAR) = '420')) 
GROUP BY entries.ID 
ORDER BY entries.submission_date DESC 
LIMIT 0, 25; 

投票表有4列。 vote_id,entry_id,user_id,值。

我想到的一个选项是SELECT entry_id FROM votes WHERE user_id = 1,并将其包含在我的查询中的AND子句中。这是可接受的/有效的吗?

E.g.

AND entries.ID NOT IN (SELECT entry_id FROM votes WHERE user_id = 1) 
+5

你试过了吗?它看起来很合理,虽然你可能想阅读[NOT EXISTS vs NOT IN](http://stackoverflow.com/questions/2246772/whats-the-difference-between-not-exists-vs-not-in-vs -left-join-where-null-null) – Andrew

+1

完美地工作!谢谢安德鲁。有时实际上写下问题来解释它澄清解决方案:) –

回答

0

一个left join用适当的where条款可能是有用的:

SELECT 
    entries.* 
FROM 
    entries 
    INNER JOIN entry_meta ON (entries.ID = entry_meta.entry_id) 
    LEFT JOIN votes ON entries.ID = votes.entry_id 
WHERE 1=1 
    AND (
     entry_meta.meta_key = 'competition_id' 
     AND CAST(entry_meta.meta_value AS CHAR) = '420') 
     AND votes.entry_id IS NULL -- This will remove any entry with votes 
) 
GROUP BY entries.ID 
ORDER BY entries.submission_date DESC 
0

这里是安德鲁的建议的实现使用存在/不存在。

select 
    e.* 
from 
    entries e 
    join entry_meta em on e.ID = em.entry_id 
where 
    em.meta_key = 'competition_id' 
    and cast(em.meta_value as char) = '420' 
    and (
    not exists (
     select 1 
     from votes v 
     where 
     v.entry_id = e.ID 
    ) 
    or exists (
     select 1 
     from votes v 
     where 
     v.entry_id = e.ID 
     and v.user_id != 1 
    ) 
) 
group by e.ID 
order by e.submission_date desc 
limit 0, 25; 

注:这通常不是一个好主意,把一个功能的where子句中(由于性能原因),但因为你是还加入的ID,你应该确定。

另外,Barranka的左连接建议可能会导致查询返回比您预期的更多的行(假设条目和投票之间存在1:多关系)。

相关问题