多次计数(*),一次性左连接

时间:2016-10-07 14:22:30

标签: sql count left-join mariadb

我有2张这样的表:

表用户:

var o = angular.element(document.querySelector('#maintwo'));
var r = o[0].innerHTML.replace('TWO','REPLACE');
angular.element(document.querySelector('#maintwo')).innerHTML = r;

使用oauth链接用户的表users_oauth,如果用户没有oauth条目,则用户创建了一个带有电子邮件/密码的帐户:

   +--------------------------+-----------------+------+-----+---------+----------------+
   | Field                    | Type            | Null | Key | Default | Extra          |
   +--------------------------+-----------------+------+-----+---------+----------------+
   | user_id                  | int(8) unsigned | NO   | PRI | NULL    | auto_increment |
   | user_email               | varchar(40)     | NO   | UNI |         |                |
   | user_login               | varchar(30)     | YES  |     | NULL    |                |
   | user_password            | varchar(40)     | YES  |     | NULL    |                |
   | user_firstname           | varchar(30)     | YES  |     | NULL    |                |
   | user_lastname            | varchar(50)     | YES  |     | NULL    |                |
   +--------------------------+-----------------+------+-----+---------+----------------+

对于两个日期之间的计数,要知道我为facebook oauth做了以下新用户的数量:

   +----------------------+-----------------+------+-----+---------+----------------+
   | Field                | Type            | Null | Key | Default | Extra          |
   +----------------------+-----------------+------+-----+---------+----------------+
   | oauth_id             | int(8) unsigned | NO   | PRI | NULL    | auto_increment |
   | oauth_user_id        | int(8) unsigned | NO   | MUL | NULL    |                |
   | oauth_google_id      | varchar(30)     | YES  | UNI | NULL    |                |
   | oauth_facebook_id    | varchar(30)     | YES  | UNI | NULL    |                |
   | oauth_windowslive_id | varchar(30)     | YES  | UNI | NULL    |                |
   +----------------------+-----------------+------+-----+---------+----------------+

对于使用google oauth的新用户的另一个请求,唯一的区别是SELECT date_format(`user_date_accountcreated`, "%Y-%m-%d") AS date, COUNT(*) AS total FROM users LEFT JOIN users_oauth ON users_oauth.oauth_user_id = users.user_id WHERE (user_date_accountcreated BETWEEN '2016-10-01 00:00:00' AND '2016-10-15 23:59:59') AND oauth_facebook_id IS NOT NULL GROUP BY year(user_date_accountcreated), month(user_date_accountcreated), day(user_date_accountcreated) 而不是oauth_google_id IS NOT NULL

oauth_facebook_id IS NOT NULL

最后一个用于windows live oauth:

SELECT date_format(`user_date_accountcreated`, "%Y-%m-%d") AS  date, COUNT(*) AS total FROM users 
LEFT JOIN users_oauth ON users_oauth.oauth_user_id = users.user_id 
WHERE (user_date_accountcreated BETWEEN '2016-10-01 00:00:00' AND '2016-10-15 23:59:59') AND oauth_google_id IS NOT NULL
GROUP BY year(user_date_accountcreated), month(user_date_accountcreated), day(user_date_accountcreated)

有没有办法合并只有SELECT date_format(`user_date_accountcreated`, "%Y-%m-%d") AS date, COUNT(*) AS total FROM users LEFT JOIN users_oauth ON users_oauth.oauth_user_id = users.user_id WHERE (user_date_accountcreated BETWEEN '2016-10-01 00:00:00' AND '2016-10-15 23:59:59') AND oauth_windowslive_id IS NOT NULL GROUP BY year(user_date_accountcreated), month(user_date_accountcreated), day(user_date_accountcreated) COUNT(*) AS total_facebookCOUNT(*) AS total_google的3个请求?

由于

1 个答案:

答案 0 :(得分:2)

您可以将where条件移至count。这称为条件聚合。

同样,当您left join并使用where条件时,它会转换为内部联接。为避免将日期条件移至left join

SELECT 
date_format(`user_date_accountcreated`, "%Y-%m-%d") AS `date`, 
COUNT(case when oauth_facebook_id IS NOT NULL then 1 end ) AS total_facebook,
COUNT(case when oauth_google_id IS NOT NULL then 1 end) AS total_google,
COUNT(case when oauth_windowslive_id IS NOT NULL then 1 end) AS total_windowslive
FROM users 
LEFT JOIN users_oauth ON users_oauth.oauth_user_id = users.user_id 
AND user_date_accountcreated BETWEEN '2016-10-01 00:00:00' AND '2016-10-15 23:59:59'
GROUP BY date_format(`user_date_accountcreated`, "%Y-%m-%d")
--year(user_date_accountcreated), month(user_date_accountcreated), day(user_date_accountcreated)