问题描述
我有 3 张这样的桌子
create table Users (id serial primary key,country varchar(100) not null);
create table tweets(id serial primary key,user_id int,text varchar(100) not null,CONSTRAINT FK_TWEETSUSERS FOREIGN KEY (user_id)
REFERENCES Users(id));
create table Logins(user_id int,client varchar(100),CONSTRAINT FK_LOGIN_USERS FOREIGN KEY (user_id)
REFERENCES Users(id));
insert into Users
values
(1,'Japan'),(2,'Moroco'),(3,(4,'India'),(5,(6,(7,(8,'China');
insert into tweets
values
(733,1,'I love #food'),(734,'I love food'),(735,2,(736,5,(737,6,(738,3,(739,8,'I love #food');
insert into Logins
values
(1,'mobile-ios'),'web'),'mobile-ios');
我需要找到用户在推文中使用“#food”的每个国家/地区的用户百分比,另一个条件是用户应该使用“移动”设备登录
到目前为止,我已经编写了以下查询 -
select t.country,count(t.country) as tweet_users
from
(select Mobile_User_Tweets.user_id,U.country from Users as U
inner join
(select distinct user_id from tweets
where text like '%#food%'
and user_id in (select distinct user_id
from Logins
where client like '%mobile-%')) as Mobile_User_Tweets
on U.id = Mobile_User_Tweets.user_id) as t
group by t.country ;
这给出了在推文中包含用户 #food 的国家/地区的用户数量
结果如下 -
country tweet_users
Japan 2
Moroco 1
China 1
我想要以下结果 -
country tweet_users
Japan 66.67 -------------> (2 out of 3 users from Japan)
Moroco 50 -------------> (1 out of 2 users from Moroco)
China 100 -------------> (1 out of 1 user from China)
我尝试了许多不同的查询来找到百分比,但没有得到结果?
有人可以帮我解决这个问题吗?
解决方法
实现您想要的结果的一种方法是在派生表中检查用户是否发布了关于 #food
的任何推文;那么您可以LEFT JOIN
将该表Users
和Logins
确定从每个国家/地区通过手机登录并发布有关食物的推文的平均用户数:
SELECT u.country,AVG(COALESCE(t.tfood,0) AND COALESCE(l.client,'') LIKE '%mobile-%') * 100 AS tweet_users
FROM Users u
LEFT JOIN Logins l ON l.user_id = u.id
LEFT JOIN (
SELECT user_id,MAX(text LIKE '%#food%') AS tfood
FROM tweets
GROUP BY user_id
) t ON t.user_id = u.id
GROUP BY u.country
输出:
country tweet_users
China 100.0000
India 0.0000
Japan 66.6667
Moroco 50.0000
如果您不想要没有符合条件的用户的国家/地区,只需在末尾添加 HAVING tweet_users > 0
:
SELECT u.country,MAX(text LIKE '%#food%') AS tfood
FROM tweets
GROUP BY user_id
) t ON t.user_id = u.id
GROUP BY u.country
HAVING tweet_users > 0
请注意,这段代码利用了这样一个事实,即在数字上下文中,MySQL 将布尔表达式视为 1(真)或 0(假)。
请注意,如果用户在 Logins
表中可能有多个条目,您也需要从中创建一个派生表:
SELECT u.country,0) AND COALESCE(l.mclient,0)) * 100 AS tweet_users
FROM Users u
LEFT JOIN (
SELECT user_id,MAX(client LIKE '%mobile-%') AS mclient
FROM Logins
GROUP BY user_id
) l ON l.user_id = u.id
LEFT JOIN (
SELECT user_id,MAX(text LIKE '%#food%') AS tfood
FROM tweets
GROUP BY user_id
) t ON t.user_id = u.id
GROUP BY u.country