Mysql 如何检查行是否存在?用两张桌子去拿?
我有两张桌子:选票和最喜欢的 以下是我的结构:Mysql 如何检查行是否存在?用两张桌子去拿?,mysql,Mysql,我有两张桌子:选票和最喜欢的 以下是我的结构: // votes // favorite +----+---------+---------+-------+ +----+---------+---------+ | id | id_post | id_user | value | | id | id_post | id_user | +----+---------+---------+--
// votes // favorite
+----+---------+---------+-------+ +----+---------+---------+
| id | id_post | id_user | value | | id | id_post | id_user |
+----+---------+---------+-------+ +----+---------+---------+
当我显示一篇文章时,我需要知道当前用户是否已经对此文章进行了投票,如果是,它的值是1还是-1?我还需要检查这篇文章是否是当前用户的最爱?那么我如何实现它呢
我的尝试:
要检查现有收藏夹,请执行以下操作:
SELECT EXISTS(SELECT 1 FROM favorites WHERE post_id={} and user_id={} LIMIT 1) as favorite
我也有同样的问题来检查是否有任何投票?但我想知道如何既能检查又能取回?我想知道,为了混合两个查询,我应该使用join吗
编辑:
以下是员额表的结构:
使用
将为您提供数据库是否一致的0或1行(包含该值)
在DBClient端,您可以检查resultset是否为空,这是对投票存在性的隐式检查
要同时获取帖子和投票,此操作应适用于日期:合并收藏夹:
SELECT p.*, v.value
FROM posts p
LEFT JOIN votes v
ON v.id_post = p.id
LEFT JOIN favorites f
ON f.id_post = p.id
WHERE
p.id={@pid} AND
v.id_user={@uid} AND
f.id_user={@uid}
使用
将为您提供数据库是否一致的0或1行(包含该值)
在DBClient端,您可以检查resultset是否为空,这是对投票存在性的隐式检查
要同时获取帖子和投票,此操作应适用于日期:合并收藏夹:
SELECT p.*, v.value
FROM posts p
LEFT JOIN votes v
ON v.id_post = p.id
LEFT JOIN favorites f
ON f.id_post = p.id
WHERE
p.id={@pid} AND
v.id_user={@uid} AND
f.id_user={@uid}
与单独查询以确定当前用户在已经查询和获取帖子后是否投票/赞成不同,您可以通过向查询检索帖子添加左连接来显著减少总体查询数量
SELECT
`posts`.`id`,
`title`,
`content`,
`by`,
`total_votes`,
`total_favorites`,
-- Use a CASE condition to return a value for votes
-- based on whether a row is returned by the LEFT JOIN
-- Change the values like 'has voted' to whatever you want them to be
CASE
WHEN `votes`.`id` IS NOT NULL THEN 'has voted'
ELSE 'has not voted'
END AS `user_has_voted`,
-- Also return the vote value, which will be NULL if no vote exists
`votes`.`value` AS `vote_value`,
-- Do the same for favorites
CASE
WHEN `favorites`.`id` IS NOT NULL THEN 'has favorited'
ELSE 'has not favorited'
END AS `user_has_favorited`
FROM
`posts`
-- Supply the user's id to the ON condition
-- for both of the joins.
LEFT JOIN `votes`
ON `posts`.`id` = `votes`.`id_post`
AND `votes`.`id_user` = <user_id>
LEFT JOIN `favorites`
ON `posts`.`id` = `favorites`.`id_post`
AND `favorites`.`id_user` = <user_id>
这样做将在一个查询中完成所有操作。使用左连接的想法是,如果存在,它将从相关表返回值,否则返回NULL。因此,在CASE语句中,您可以检查IS NOT NULL以确定投票/收藏夹是否存在。而不是单独查询以确定当前用户在查询和获取帖子后是否投票/收藏夹,通过向查询检索帖子添加左连接,可以显著减少查询的总体数量
SELECT
`posts`.`id`,
`title`,
`content`,
`by`,
`total_votes`,
`total_favorites`,
-- Use a CASE condition to return a value for votes
-- based on whether a row is returned by the LEFT JOIN
-- Change the values like 'has voted' to whatever you want them to be
CASE
WHEN `votes`.`id` IS NOT NULL THEN 'has voted'
ELSE 'has not voted'
END AS `user_has_voted`,
-- Also return the vote value, which will be NULL if no vote exists
`votes`.`value` AS `vote_value`,
-- Do the same for favorites
CASE
WHEN `favorites`.`id` IS NOT NULL THEN 'has favorited'
ELSE 'has not favorited'
END AS `user_has_favorited`
FROM
`posts`
-- Supply the user's id to the ON condition
-- for both of the joins.
LEFT JOIN `votes`
ON `posts`.`id` = `votes`.`id_post`
AND `votes`.`id_user` = <user_id>
LEFT JOIN `favorites`
ON `posts`.`id` = `favorites`.`id_post`
AND `favorites`.`id_user` = <user_id>
select
p.id_post,
if(f.favorite is null, 'No', 'Yes') favorite,
if(v.vote is null, 0, v.vote) vote
from
posts p
left join
(select
id_post, id_post favorite
from
favorites
where
id_user = 100 and id_post = 4) f ON (p.id_post = f.id_post)
left join
(select
id_post, value vote
from
votes
where
id_user = 100 and id_post = 4) v ON (p.id_post = v.id_post)
where
p.id_post = 4;
这样做将在一个查询中完成所有操作。使用左连接的想法是,如果存在,它将从相关表返回值,否则返回NULL。因此,在CASE语句中,您可以检查IS NOT NULL以确定投票/收藏夹是否存在
select
p.id_post,
if(f.favorite is null, 'No', 'Yes') favorite,
if(v.vote is null, 0, v.vote) vote
from
posts p
left join
(select
id_post, id_post favorite
from
favorites
where
id_user = 100 and id_post = 4) f ON (p.id_post = f.id_post)
left join
(select
id_post, value vote
from
votes
where
id_user = 100 and id_post = 4) v ON (p.id_post = v.id_post)
where
p.id_post = 4;
更换id_post=4和id_user=100
当投票为0时,表示用户尚未评分
更换id_post=4和id_user=100
当投票为0时,表示用户尚未评分请同时发布post表的结构。这应该可以通过使用联接的一个查询实现。我在posts表中有两列名为total_votes,total_favorites,我在插入投票或favorite表后通过触发器更新它们,无论如何,我认为posts表需要单独的查询。但我想知道是否有一列像posts.id这样的列将其与其他表关联。您是否希望为用户显示帖子?使用左连接应该可以在一个查询中获得所有这些信息。@MichaelBerkowski请查看我的更新。我需要:标题,内容,作者,总票数,总收藏夹,是否有用户标记为收藏夹的行,是否有用户投票?它的价值是什么?请同时发布post表的结构。这应该可以通过使用联接的一个查询实现。我在posts表中有两列名为total_votes,total_favorites,我在插入投票或favorite表后通过触发器更新它们,无论如何,我认为posts表需要单独的查询。但我想知道是否有一列像posts.id这样的列将其与其他表关联。您是否希望为用户显示帖子?使用左连接应该可以在一个查询中获得所有这些信息。@MichaelBerkowski请查看我的更新。我需要:标题,内容,作者,总票数,总收藏夹,是否有用户标记为收藏夹的行,是否有用户投票?它的价值是什么?这是一个多么清晰有力的答案,谢谢,只有一件事:这意味着什么:当favorites.id不为空时?vote.id应与post相同。id@Sajad左联接将返回匹配行(如果存在),但如果不存在,则投票或收藏夹表中的所有列都将返回NULL。因此,此条件测试id列中联接返回的空值,以确定行是否存在。也可能是favorites.id_post不为空时。你使用哪一列其实并不重要。@Sajad不管怎样,我很高兴能帮上忙。祝你好运。@Sajad我不确定哪一个会更好。您需要检查解释选择。。。以查看查询是否正确使用了复合索引。我想会的。查询总数要复杂得多。使用触发器更新它们将始终允许您的查询运行得更快,因此我可能会像使用触发器一样保留它。否则,我可能会考虑通过查询每个帖子T的总和来创建一个临时表。
o避免必须实时检索总和,但触发器更容易。这是一个多么清晰而有力的答案,谢谢,只有一件事:这意味着什么:当favorites.id不为NULL时?vote.id应与post相同。id@Sajad左联接将返回匹配行(如果存在),但如果不存在,则投票或收藏夹表中的所有列都将返回NULL。因此,此条件测试id列中联接返回的空值,以确定行是否存在。也可能是favorites.id_post不为空时。你使用哪一列其实并不重要。@Sajad不管怎样,我很高兴能帮上忙。祝你好运。@Sajad我不确定哪一个会更好。您需要检查解释选择。。。以查看查询是否正确使用了复合索引。我想会的。查询总数要复杂得多。使用触发器更新它们将始终允许您的查询运行得更快,因此我可能会像使用触发器一样保留它。否则,我可能会考虑通过查询每个帖子的总和来创建一个临时表,以防止不得不实时地检索和,但是触发器更容易。