用于检查另一个表中是否存在值的SQL查询

时间:2014-07-14 18:21:21

标签: mysql sql

我有一个SQL查询,它完成了我需要做的大部分工作,但我遇到了问题。

总共有3张桌子。 entriesentry_metavotes

我需要在entries表中的competition_id = 420时从entry_meta获取整行,并且votes中的ID不存在,或者它确实存在但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,value。

我想到的一个选项是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)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

以下是Andrew建议使用存在/不存在的实现。

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:多的关系)。