MySQL 计数唯一列,其中其他列在 Group By 中具有单个值

MySQL Count Unique Of One Column Where Other Column Has Single Value In Group By

请看下面的table。我想计算不同的访问者 (visitor_id),按组分组 (group_id),但只计算结果始终为该访问者 'declined' 的访问者。

类似

SELECT group_id, COUNT(DISTINCT visitor_id) AS always_declines
FROM customer_actions 
WHERE outcome='declined' [[AND HAS NEVER BEEN IN ('purchased')]]
GROUP BY group_id;

这是我的 table:

的简化版本
SELECT * FROM customer_actions;
+----+------------+-----------+----------+
| id | visitor_id | outcome   | group_id |
+----+------------+-----------+----------+
|  1 |          5 | purchased |        1 |
|  2 |          5 | purchased |        1 |
|  3 |          6 | purchased |        1 |
|  4 |          7 | declined  |        1 |
|  5 |          6 | declined  |        1 |
|  6 |          7 | purchased |        1 |
|  7 |          8 | declined  |        1 |
|  8 |          8 | declined  |        1 |
+----+------------+-----------+----------+
8 rows in set (0.00 sec)

所以基本上,如果它有效,我正在寻找返回的第一行也是唯一一行(在这种情况下):

group_id = 1

always_declines = 1(对应只拒绝过的访客8)

not exists 运算符应该可以解决问题:

SELECT   group_id, COUNT(DISTINCT visitor_id) AS always_declines
FROM     customer_actions  ca1
WHERE    NOT EXISTS (SELECT *
                     FROM   customer_actions ca2
                     WHERE  ca1.group_id = ca2.group_id AND
                            ca1.visitor_id = ca2.visitor_id AND
                            ca2.outcome != 'declined')
GROUP BY group_id;

解决这个问题的一种方法是作为两个聚合。首先,按组和访客进行聚合,以获取合适的访客。然后计算剩余的行数:

SELECT group_id, count(*) AS always_declines
FROM (SELECT group_id, visitor_id
      FROM customer_actions 
      GROUP BY group_id, visitor_id
      HAVING SUM(outcome <> 'declined') = 0
     ) gv
GROUP BY group_id;