对符合选择条件的SQL中的条目进行计数

问题描述

我有一个表,用于存储用户为产品创建的帐户类型。有3种可能的路径。

  1. 他们可以创建一个试用帐户,然后创建一个完整帐户。
  2. 他们只能创建一个完整的帐户。
  3. 他们可以创建试用帐户。

在第一种情况下,将创建2个条目,而在其他情况下,将创建1个条目。下面的示例源表:

+------+--------------+
| user | account_type |
+------+--------------+
| 1    | trial        |
+------+--------------+
| 1    | full         |
+------+--------------+
| 2    | full         |
+------+--------------+
| 3    | full         |
+------+--------------+
| 4    | trial        |
+------+--------------+
| 4    | full         |
+------+--------------+
| 5    | trial        |
+------+--------------+
| 5    | full         |
+------+--------------+
| 6    | trial        |
+------+--------------+
| 7    | full         |
+------+--------------+

我想计算创建一个试用帐户然后再创建一个完整帐户的用户数量,以及直接创建一个完整帐户的用户数量。预计的下表如下:

+-------------------+------------------------+
| full_account_only | trial_and_full_account |
+-------------------+------------------------+
| 124               | 256                    |
+-------------------+------------------------+

到目前为止,我的查询是:

select sum(case
             when account_type_cnt = 1 then
              1
           end) as "full_account_only",sum(case
             when account_type_cnt = 2 then
              1
           end) as "trial_and_full_account "
  from (select user,count(distinct(account_type)) as account_type_cnt
          from tbl
         group by user)

,但我意识到,这将无法满足仅计算完整帐户的用户的计数标准。有人可以帮助解决这个问题吗?

解决方法

您可以使用两个级别的聚合。我会将计数放在单独的行中,如下所示:

select num_trial,num_full,count(*) as num_users
from (select user,sum(case when account_type = 'trial' then 1 else 0 end) as num_trial,sum(case when account_type = 'full' then 1 else 0 end) as num_full
      from t
      group by user
     ) u
group by num_trial,num_full;

您可以轻松地对此进行修改,以将值放在列中:

select sum(case when num_trial > 0 and num_full = 0 then 1 else 0 end) as only_trial,sum(case when num_full > 0 and num_trial = 0 then 1 else 0 end) as only_full,sum(case when num_full > 0 and num_trial > 0 then 1 else 0 end) as both
from (select user,num_full;
,

与Gordon类似的方法,但实现方式略有不同,部分是因为我更喜欢在计算事物时使用count,而不是求和。您可以将计数作为标志来获取每个用户存在的帐户类型:

select usr,count(case when account_type = 'trial' then account_type end) as trial_cnt,count(case when account_type = 'full' then account_type end) as full_cnt
from tbl
group by usr
USR | TRIAL_CNT | FULL_CNT
--: | --------: | -------:
  6 |         1 |        0
  2 |         0 |        1
  4 |         1 |        1
  3 |         0 |        1
  5 |         1 |        1
  7 |         0 |        1
  1 |         1 |        1

,然后将其用作内部查询以及另一层条件聚合:

select
  count(case when trial_cnt > 0 then usr end) as trial,count(case when full_cnt > 0 then usr end) as full,count(case when full_cnt > 0 and trial_cnt = 0 then usr end) as full_only,count(case when full_cnt > 0 and trial_cnt > 0 then usr end) as trial_and_full
from (
  select usr,count(case when account_type = 'trial' then usr end) as trial_cnt,count(case when account_type = 'full' then usr end) as full_cnt
  from tbl
  group by usr
)
TRIAL | FULL | FULL_ONLY | TRIAL_AND_FULL
----: | ---: | --------: | -------------:
    4 |    6 |         3 |              3

db<>fiddle

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...