【问题标题】:Get all the users count according to type in one query instead of multiple query in mysql根据输入一个查询而不是mysql中的多个查询获取所有用户数
【发布时间】:2018-07-11 19:39:18
【问题描述】:

我正在尝试编写一个 MySQL 查询,我只想从一个表中获取数据。结构如下所示:

+--------------------+------------------+------+-----+----------+----------------+
| Field              | Type             | Null | Key | Default  | Extra          |
+--------------------+------------------+------+-----+----------+----------------+
| id                 | int(10) unsigned | NO   | PRI | NULL     | auto_increment |
| name               | varchar(255)     | NO   |     | NULL     |                |
| lastname           | varchar(255)     | NO   |     | NULL     |                |
| slug               | text             | NO   |     | NULL     |                |
| gender             | varchar(225)     | YES  |     | NULL     |                |
| balance            | double(50,6)     | YES  |     | NULL     |                |
| email              | varchar(255)     | NO   |     | NULL     |                |
| password           | varchar(255)     | NO   |     | NULL     |                | 
| city               | varchar(255)     | NO   |     | NULL     |                |
| country            | varchar(255)     | NO   |     | NULL     |                |
| statename          | varchar(255)     | NO   |     | NULL     |                |
| countryname        | varchar(255)     | NO   |     | NULL     |                |
| dob                | date             | YES  |     | NULL     |                |
| membership         | varchar(255)     | YES  |     | standard |                |
| status             | varchar(255)     | NO   |     | NULL     |                |
| marital_status     | varchar(255)     | NO   |     | NULL     |                |
| description        | text             | NO   |     | NULL     |                |
| user_id            | int(10) unsigned | YES  | MUL | NULL     |                |
| active             | smallint(6)      | NO   |     | 1        |                |
| registertype       | varchar(255)     | NO   |     | unpaid   |                |
| created_at         | timestamp        | YES  |     | NULL     |                |
| updated_at         | timestamp        | YES  |     | NULL     |                              
+--------------------+------------------+------+-----+----------+----------------+

现在我想用下面的列选择这样的数据:

1) created_at (will be a date)
2) total_registrations (will be total count)
3) paid_member (count of total member where registertype=paid on a specific date)
4) unpaid_member (count of total member where registertype=unpaid on a specific date wise)

到目前为止,我通过以下查询成功获得了这样的结果:

select DATE(`created_at`) as created_at, count(*) as total_registrations 
from en_customers 
where DATE(`created_at`)  between date_sub(CURDATE(), interval 7 day) AND CURDATE() 
    AND registertype="paid"  
group by DATE(`created_at`);

从这个查询我得到这个结果:

+------------+-----------+
| created_at | total_reg |
+------------+-----------+
| 2018-07-04 |         7 |
| 2018-07-05 |         7 |
| 2018-07-06 |         5 |
| 2018-07-07 |         4 |
| 2018-07-08 |         8 |
| 2018-07-09 |        13 |
| 2018-07-10 |        15 |
| 2018-07-11 |        14 |
+------------+-----------+

但我无法使用我刚刚显示的列获取记录。

谢谢(提前)!

【问题讨论】:

  • 语法显然是 MySQL -- 而不是 SQL Server。我更改了标签。今后,请适当标记。
  • 当然,我会确保正确提及标签。

标签: mysql sql


【解决方案1】:

这样做:

select DATE(`created_at`) as created_at, count(*) as total_registrations 
    ,sum(case when registertype='paid' then 1 else 0 end) as paid_member
    ,sum(case when registertype='unpaid' then 1 else 0 end) as unpaid_member
from en_customers 
where DATE(`created_at`)  between date_sub(CURDATE(), interval 7 day) AND CURDATE()  
group by DATE(`created_at`);

该技术称为“条件聚合”。

注意我从WHERE 子句中删除了registertype="paid" 条件。

【讨论】:

  • 效果太棒了!这是最快的方法吗?或者有没有更快的查询方式?
  • 是的,我看到另外一个人的回答和你的一样:)
  • SUM vs COUNT 我猜 sum 可能需要更多处理,而 count 需要更少处理。您分享的结果在 0.06 秒内显示,count 在 0.05 秒内显示。
  • SUM()COUNT() 做不同的事情。 0 仍在“计数”中。
【解决方案2】:

COUNT 函数中使用CASE WHEN

select DATE(`created_at`) as created_at,
       count(*) as total_registrations,
       COUNT(CASE WHEN registertype='paid' THEN 1 END) as paid_member,
       COUNT(CASE WHEN registertype='unpaid' THEN 1 END) as unpaid_member 
from en_customers 
where DATE(`created_at`)  between date_sub(CURDATE(), interval 7 day) AND CURDATE() 
group by DATE(`created_at`);

【讨论】:

    【解决方案3】:

    您可以对过滤后的值使用 sum

    select DATE(`created_at`) as created_at
          , count(*) as total_registrations 
          , sum(case when registertype='paid' then 1 else 0 end) paid_member
          , sum(case when registertype='unpaid' then 1 else 0 end) unpaid_member
    from en_customers 
    where DATE(`created_at`)  between date_sub(CURDATE(), interval 7 day) AND CURDATE() 
    
    group by DATE(`created_at`);
    

    【讨论】:

    • SUM 和 COUNT 哪个更好?
    • count ..count(*) 有值的行数,th count(colname) 统计列不为空的行数,count(distinct colname) 统计不同的值不为空,但对于过滤行,您应该使用 sum 仅对行中的真实值加 1
    猜你喜欢
    • 2020-09-11
    • 1970-01-01
    • 2012-06-11
    • 2018-09-11
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多