使用表联接过滤的MySQL计数查询
我有一个users表、posts表、private表和user_stats表:使用表联接过滤的MySQL计数查询,mysql,join,count,Mysql,Join,Count,我有一个users表、posts表、private表和user_stats表: users user_id | user_name -------------------- 1 | tony 2 | steph 3 | lizzy 4 | adam posts post_id user_id sugg_by private (0 is public, 1 is p
users
user_id | user_name
--------------------
1 | tony
2 | steph
3 | lizzy
4 | adam
posts
post_id user_id sugg_by private (0 is public, 1 is private to authorized users)
-----------------------------------------------------
1 1 2 0
2 2 2 1
3 2 2 1
4 2 4 1
5 2 2 1
6 2 3 0
private
private_id post_id authorized_user_id
-----------------------------------------------
1 2 4
2 2 3
3 4 4
4 5 1
5 5 3
user_stats
user_id orig_posts_count(user_id=sugg_by in posts) sugg_posts_count(user_id<>sugg_by in posts)
-----------------------------------------------------------------------------------------------------
1 0 1
2 3 2
3 0 0
4 0 0
然而,它被定义为:
我相信这是因为在p.user\u id=us.user\u id
如果我将其转换为JOIN posts p ON p.user\u id=us.user\u id和p.sugg\u by='2'
(与display\u orig\u posts\u COUNT的第一个计数相匹配),那么display\u orig\u posts\u COUNT是1,这是正确的,但是display\u sugg\u posts\u COUNT在3处是不正确的。我得到了正确的显示原帖数和错误的显示原帖数。作为:
如果我将其转换为通过'2'将p.user\u id=us.user\u id和p.sugg\u上的posts p连接到中(这与display\u sugg\u posts\u COUNT的第二个计数相匹配),那么display\u orig\u posts\u COUNT是2,这是不正确的,但是display\u sugg\u posts\u COUNT是正确的2。作为:
基本上,登录用户if steph应该返回'posterview',但是使用COUNT的任何其他用户应该只看到公共(private 0)或(private 1)的帖子(如果它们是帖子的一部分),然后根据COUNT子句中的条件进行计数,以获得所述的正确输出。我已经被困在这个问题上好几个小时了。知道如何让查询正常工作吗?
注意:每个示例输出都包含小提琴。将查询更改为:
SELECT u.user_id, us.orig_posts_count, us.sugg_posts_count,
IF(us.user_id='4', 'posterview',
COUNT(CASE
WHEN p.sugg_by='2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
END)) AS display_orig_posts_count,
IF(us.user_id='4', 'posterview',
COUNT(CASE
WHEN p.sugg_by<>'2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
END)) AS display_sugg_posts_count
FROM users AS u
JOIN user_stats AS us ON u.user_id=us.user_id
JOIN posts AS p ON p.user_id=us.user_id
LEFT JOIN private AS pv ON pv.post_id=p.post_id AND pv.authorized_user_id='4'
WHERE u.user_id='2'
GROUP BY u.user_id, us.orig_posts_count, us.sugg_posts_count
我们希望计算什么:
display_orig_posts_count = 1:
post_id=2: because p.sugg_by=2, p.private=1 AND (is_authorized)
display_sugg_posts_count = 3:
post_id=4: because p.sugg_by<>'2', p.private=1 AND (is_authorized)
post_id=6: because p.sugg_by<>'2', p.private=0
对于display\u sugg\u posts\u count
,让我们再次明确地查找这些内容:
COUNT(CASE
WHEN p.sugg_by<>'2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
)
计数(大小写)
当p.sugg_由'2'和(p.private='0'或pv.post_id不为NULL)表示时
那么1
否则无效
)
使用聚合函数时使用分组依据
如果正确地对聚合函数进行分组,则也不需要限制1。每个用户只能返回一行
将查询更改为:
SELECT u.user_id, us.orig_posts_count, us.sugg_posts_count,
IF(us.user_id='4', 'posterview',
COUNT(CASE
WHEN p.sugg_by='2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
END)) AS display_orig_posts_count,
IF(us.user_id='4', 'posterview',
COUNT(CASE
WHEN p.sugg_by<>'2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
END)) AS display_sugg_posts_count
FROM users AS u
JOIN user_stats AS us ON u.user_id=us.user_id
JOIN posts AS p ON p.user_id=us.user_id
LEFT JOIN private AS pv ON pv.post_id=p.post_id AND pv.authorized_user_id='4'
WHERE u.user_id='2'
GROUP BY u.user_id, us.orig_posts_count, us.sugg_posts_count
我们希望计算什么:
display_orig_posts_count = 1:
post_id=2: because p.sugg_by=2, p.private=1 AND (is_authorized)
display_sugg_posts_count = 3:
post_id=4: because p.sugg_by<>'2', p.private=1 AND (is_authorized)
post_id=6: because p.sugg_by<>'2', p.private=0
对于display\u sugg\u posts\u count
,让我们再次明确地查找这些内容:
COUNT(CASE
WHEN p.sugg_by<>'2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
)
计数(大小写)
当p.sugg_由'2'和(p.private='0'或pv.post_id不为NULL)表示时
那么1
否则无效
)
使用聚合函数时使用分组依据
如果正确地对聚合函数进行分组,则也不需要限制1。每个用户只能返回一行
到目前为止,这是最好的详细解释。快速提示:如果我将us.orig\u posts\u计数、us.sugg\u posts\u计数从按用户id分组、us.orig\u posts\u计数、us.sugg\u posts\u计数中删除,而改为按用户id分组是否重要?谢谢你的支持!在这种情况下这无关紧要,因为每个用户id
值只有一个原始帖子数/sugg\u帖子数
对。事实上,您实际上不需要在此查询中按任何内容进行分组,因为查询无论如何都应该只返回每个user\u id
值的一行。不过,我这样做是为了明确说明目的,一些SQL系统不允许您对非聚合字段使用聚合函数(如COUNT
,MAX
,AVG
,等等),除非您按每个非聚合字段分组。到目前为止,这是最详细的解释。快速提示:如果我将us.orig\u posts\u计数、us.sugg\u posts\u计数从按用户id分组、us.orig\u posts\u计数、us.sugg\u posts\u计数中删除,而改为按用户id分组是否重要?谢谢你的支持!在这种情况下这无关紧要,因为每个用户id
值只有一个原始帖子数/sugg\u帖子数
对。事实上,您实际上不需要在此查询中按任何内容进行分组,因为查询无论如何都应该只返回每个user\u id
值的一行。不过,我这样做是为了明确说明目的,一些SQL系统不允许您对非聚合字段使用聚合函数(如COUNT
,MAX
,AVG
,等等),除非您按每个非聚合字段分组。
display_orig_posts_count = 3:
post_id=2: pv.post_id is not null (fails ISNULL() check)
post_id=4: pv.post_id is not null (fails ISNULL() check)
post_id=6: p.private='0' (fails p.private='1' check)
display_sugg_posts_count = 5:
post_id=2: pv.post_id is not null (fails ISNULL() check)
post_id=3: p.sugg_by='2' (fails p.sugg_by<>'2' check)
post_id=4: pv.post_id is not null (fails ISNULL() check)
post_id=5: p.sugg_by='2' (fails p.sugg_by<>'2' check)
post_id=6: p.private='0' (fails p.private='1' check)
display_orig_posts_count = 1:
post_id=2: pv.post_id is not null (fails ISNULL() check)
display_sugg_posts_count = 3:
post_id=2: pv.post_id is not null (fails ISNULL() check)
post_id=3: p.sugg_by='2' (fails p.sugg_by<>'2' check)
post_id=5: p.sugg_by='2' (fails p.sugg_by<>'2' check)'
display_orig_posts_count = 2:
post_id=4: pv.post_id is not null (fails ISNULL() check)
post_id=6: p.private='0' (fails p.private='1' check)
display_sugg_posts_count = 2:
post_id=4: pv.post_id is not null (fails ISNULL() check)
post_id=6: p.private='0' (fails p.private='1' check)
display_orig_posts_count = 1:
post_id=2: because p.sugg_by=2, p.private=1 AND (is_authorized)
display_sugg_posts_count = 3:
post_id=4: because p.sugg_by<>'2', p.private=1 AND (is_authorized)
post_id=6: because p.sugg_by<>'2', p.private=0
COUNT(CASE
WHEN p.sugg_by='2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
)
COUNT(CASE
WHEN p.sugg_by<>'2' AND (p.private='0' OR pv.post_id IS NOT NULL)
THEN 1
ELSE NULL
)