昨天我已经测试了一个查询好几个小时了,但一直没有成功。这是三张表:
USERS:
#### id: 1 ##### name: Admin ##### Hometown: The Hague
POSTS:
#### id: 1 ##### userid: 1 ##### title: Test I ##### opinion: agree
#### id: 2 ##### userid: 1 ##### title: Nope.. ##### opinion: disagree
REACTIONS:
#### id: 1 ##### userid: 1 ##### opinion: agree
#### id: 2 ##### userid: 1 ##### opinion: disagree
这就是我想要的:我想要用户的基本信息(姓名、家乡等),我想统计这个人发布了多少赞美(意见后:同意)、多少抱怨(意见后,不同意)、有多少正面反应(意见后)和有多少负面反应(意见前:不同意)。
这是我现在使用的查询:
SELECT
u.name, u.hometown,
SUM(IF(r.opinion="disagree",1,0)) AS agrees
SUM(IF(r.opinion="disagree",1,0)) AS disagrees,
SUM(IF(p.opinion="agree",1,0)) AS compliments,
SUM(IF(p.opinion="disagree",1,0)) AS complaints
FROM
users AS u
LEFT JOIN
reactions AS r
ON
r.userid = u.id
LEFT JOIN
posts AS p
ON
p.userid = u.id
WHERE
u.id = 1
问题是,这并没有给我正确的信息。它返回8个阳性反应的值,尽管DB中只有两个反应。
我认为这与GROUP BY p.id,r.id有关,但我试过了,但没有成功。。。有人能启发我吗?
提前感谢!
这不是分组,连接是将一个表中的多个记录连接到另一个表的单个记录。这会导致重复。
例如,对于用户表中的单个条目,您可能在反应中有3条响应,在帖子中有3个响应。您的查询返回了9条记录,因为该用户的所有反应都与该用户的全部帖子相关联。。。
userid | reaction_id | post_id
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
这意味着你需要将反应与帖子分开汇总。。。
SELECT
u.name, u.hometown,
r.agrees
r.disagrees,
p.compliments,
p.complaints
FROM
users AS u
LEFT JOIN
(
SELECT
userid,
SUM(IF(r.opinion="agree",1,0)) AS agrees
SUM(IF(r.opinion="disagree",1,0)) AS disagrees,
FROM
reactions
GROUP BY
userrid
)
AS r
ON r.userid = u.id
LEFT JOIN
(
SELECT
userid,
SUM(IF(p.opinion="agree",1,0)) AS compliments,
SUM(IF(p.opinion="disagree",1,0)) AS complaints
FROM
posts
GROUP BY
userid
)
AS p
ON p.userid = u.id
WHERE
u.id = 1
根据您的DBMS,您可能可以执行以下操作:
SELECT
*,
(SELECT COUNT(*) FROM POSTS WHERE POSTS.userid = USERS.id and opinion = 'agree') compliments,
(SELECT COUNT(*) FROM POSTS WHERE POSTS.userid = USERS.id and opinion = 'disagree') complaints,
(SELECT COUNT(*) FROM REACTIONS WHERE REACTIONS.userid = USERS.id and opinion = 'agree') positive_reactions,
(SELECT COUNT(*) FROM REACTIONS WHERE REACTIONS.userid = USERS.id and opinion = 'disagree') negative_reactions
FROM USERS
怎么样?
select id, name, hometown, sum(agrees) agrees, sum(disagrees) disagrees,
sum(compliments) compliments, sum(complaints) complaints
from (
select u.id, u.name, u.hometown,
if(p.opinion = 'agree', 1, 0) agrees,
if(p.opinion = 'disagree', 1, 0) disagrees,
0 compliments, 0 complaints
from users u
left join posts p on u.id = p.userid
union all
select u.id, u.name, u.hometown,
0, 0,
if(r.opinion = 'agree', 1, 0),
if(r.opinion = 'disagree', 1, 0)
from users u
left join reactions r on u.id = r.userid
) as S
group by id, name, hometown
select users.name, users.hometown, myPosts.compliments, myPosts.complaints, myReaction.agrees, myReaction.disagrees
from Users users
LEFT JOIN
(
select post.userid as userid
, SUM(CASE WHEN post.opinion = 'agree' THEN 1 END) as compliments
, SUM(CASE WHEN post.opinion = 'disagree' THEN 1 END) as complaints
from Posts post
group by post.userid
) as myPosts
on users.id = myPosts.userid
LEFT JOIN
(
select reaction.userid as userid
, SUM(CASE WHEN reaction.opinion = 'agree' THEN 1 END) as agrees
, SUM(CASE WHEN reaction.opinion = 'disagree' THEN 1 END) as disagrees
from Reaction reaction
group by reaction.userid
) as myReaction
on users.id = myReaction.userid