我有一个SQL查询,它完成了我需要做的大部分工作,但我遇到了问题。
总共有3张桌子。 entries
,entry_meta
和votes
。
我需要在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)
答案 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:多的关系)。