如何在 sql 中的一个组中查找内部连接作为子查询的百分比?

How to find percentage within a group in sql that has inner join as subquery?

我有 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,'Japan'),
(4,'India'),
(5,'India'),
(6,'Japan'),
(7,'Moroco'),
(8,'China');
                     
insert into tweets
values
(733,1,'I love #food'),
(734,1,'I love food'),
(735,2,'I love #food'),
(736,5,'I love food'),
(737,6,'I love #food'),
(738,3,'I love #food'),
(739,8,'I love #food');      
                     
insert into Logins
values
(1,'mobile-ios'),
(2,'mobile-ios'),
(3,'mobile-ios'),
(4,'web'),
(8,'mobile-ios');

我需要找出每个国家/地区的用户在其推文中使用“#food”的用户百分比,另一个条件是用户应该使用 'mobile' 设备

登录

到目前为止,我已经编写了以下查询 -

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)

我尝试了很多不同的查询来查找百分比,但一直无法获得结果?

有人可以帮我解决这个问题吗?

获得所需结果的一种方法是检查派生的 table 用户是否发布了关于 #food 的任何推文;然后你可以 LEFT JOIN table 到 UsersLogins 来确定每个国家/地区使用手机登录并发布有关食物的推文的平均用户数:

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,
       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
HAVING tweet_users > 0

Demo on dbfiddle

请注意,此代码利用了以下事实:在数字上下文中,MySQL 将布尔表达式视为 1(真)或 0(假)。

请注意,如果用户可能在 Logins table 中有多个条目,您也需要从中创建一个派生 table:

SELECT u.country,
       AVG(COALESCE(t.tfood, 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

Demo on dbfiddle