如果一堆列满足某些条件而GROUP BY两次,怎么不COUNT?

问题描述 投票:2回答:2

SQLFiddle Demo

我有一张像这样的桌子sample

SAMPLE的表格

+------------+------------------------+--------+------+
| id_laporan | id_laporan_rekomendasi | status | id   |
+------------+------------------------+--------+------+
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      3 | 01   |
|          8 |                      3 |      2 | 01   |
|          8 |                      3 |      2 | 01   |
|          8 |                      4 |      2 | 01   |
|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      3 | 02   |
|          7 |                      5 |      2 | 02   ||
|          7 |                      5 |      3 | 02   |
+------------+------------------------+--------+------+

我想GROUP BYidCOUNT/SUM多少id当一些列遇到一些条件。对于制作可能更有名的问题,首先我将把id分为两部分

Id:01

+------------+------------------------+--------+------+
| id_laporan | id_laporan_rekomendasi | status | id   |
+------------+------------------------+--------+------+
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      2 | 01   |
|          3 |                      2 |      3 | 01   |
|          8 |                      3 |      2 | 01   |
|          8 |                      3 |      2 | 01   |
|          8 |                      4 |      2 | 01   |

Id:02

|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      2 | 02   |
|          7 |                      1 |      3 | 02   |
|          7 |                      5 |      2 | 02   ||
|          7 |                      5 |      3 | 02   |
+------------+------------------------+--------+------+

首先看看id : 01部分。您可以在id_laporan部分看到id : 01列,它有id 38,而在id_laporan旁边有id_laporan_rekomendasi列。对于id_laporan : 3它有id_laporan_rekomendasi2id_laporan : 8它有id_laporan_rekomendasi34

现在,id_laporan_rekomendasi列中的每一行都有statusid_laporan_rekomendasi旁边的一列)。简而言之,我之前解释的就是这样:

Id_report:3

+------------+------------------------+--------+
| id_laporan | id_laporan_rekomendasi | status |
+------------+------------------------+--------+
|          3 |                      2 |      2 |
|          3 |                      2 |      2 |
|          3 |                      2 |      2 |
|          3 |                      2 |      3 | 

id_report:8

+------------+------------------------+--------+
| id_laporan | id_laporan_rekomendasi | status |
+------------+------------------------+--------+
|          8 |                      3 |      2 |
|          8 |                      3 |      2 | 
|          8 |                      4 |      2 | 

每个id_laporan_rekomendasi都有status。对于id_laporan_rekomendasi和右栏中的每个不同的id,列status,至少有一个数据3,而不是2或其他数字,它将被视为1其他,它将被视为0

所以对于Id_laporan:3它计为1,对于Id_laporan:8它计为0因为即使**Id_laporan:8**有两个不同的id为列id_laporan_rekomendasi但列status没有数据3然后它算作0。例如,表格如下所示

样品

id_report:8

+------------+------------------------+--------+
| id_laporan | id_laporan_rekomendasi | status |
+------------+------------------------+--------+
|          8 |                      3 |      2 |
|          8 |                      3 |      3 | 
|          8 |                      4 |      3 | 

然后它将被计为2,因为对于每个不同id的id_laporan_rekomendasi,它将被视为1。我们可以假设该表满足条件(正如我之前解释的,在此样本之上)。根据我的解释,这对**Id_laporan:3****Id_laporan:8**意味着,他们有数据10。在我计算这些之后,我必须SUM1的那些(0id:01)数据。这些方法与id:02相同。所以预期的输出将如下所示。

其他情况

那么如果状态3已经在id_laporan_rekomendasi中间会发生什么? ,id肯定会在status = 3中间跳过id_laporan_rekomendasi。实际上,没有一种情况可以在同一个3中找到两个数据id_laporan_rekomendasi。它看起来像这样

+------------+------------------------+--------+
| id_laporan | id_laporan_rekomendasi | status |
+------------+------------------------+--------+
|          3 |                      2 |      2 | // 01 : 0, because status = 2
|          3 |                      2 |      3 | // 01 : 1, calculation function works because status = 3
|          3 |                      2 |      2 | // 01 : 1, because status = 2
|          3 |                      2 |      2 | // 01 : 1, because status = 2

重要说明:每个不同的id_laporan_rekomendasi只有一个数据状态= 3,因此没有在同一个3中发现两次status = id_laporan_rekomendasi的情况,如下所示

错误的情景

+------------+------------------------+--------+
| id_laporan | id_laporan_rekomendasi | status |
+------------+------------------------+--------+
|          3 |                      2 |      2 | 
|          3 |                      2 |      3 | // Data status = 3, okay, for id_laporan_rekomendasi = 2, i dont need to check for the rest of id_laporan_rekomendasi's status, good grief, i will skip to the next id_laporan_rekomendasi` maybe, i will check id_laporan_rekomendasi = 3 
|          3 |                      2 |      3 | // what is this... ther is no way...
|          3 |                      2 |      2 | 

这是我对我的情况所期望的输出

+------+--------------+
| id   | count        |
+------+--------------+
| 01   |      1       |     
| 02   |      2.      |
+------+--------------+

为什么我期望的结果就像上面的表一样,基于第一个表,计算应该是这样的:

+------------+------------------------+--------+------+
| id_laporan | id_laporan_rekomendasi | status | id   |
+------------+------------------------+--------+------+
|          3 |                      2 |      2 | 01   | // 01 : 0, because status 2
|          3 |                      2 |      2 | 01   | // 01 : 0, because status 2
|          3 |                      2 |      2 | 01   | // 01 : 0, because status 2
|          3 |                      2 |      2 | 01   | // 01 : 0, because status 2
|          3 |                      2 |      2 | 01   | // 01 : 0, because status 2
|          3 |                      2 |      3 | 01   | // 01 : 1, at this point the calculation works because status 3
|          8 |                      3 |      2 | 01   | // 01 : 1, because status 2
|          8 |                      3 |      2 | 01   | // 01 : 1, because status 2 
|          8 |                      4 |      2 | 01   | // 01 : 1, because status 2 
|          7 |                      1 |      2 | 02   | // 02 : 0, because status 2 
|          7 |                      1 |      2 | 02   | // 02 : 0, because status 2 
|          7 |                      1 |      2 | 02   | // 02 : 0, because status 2 
|          7 |                      1 |      3 | 02   | // 02 : 1, at this point the calculation works because status 3
|          7 |                      5 |      2 | 02   | // 02 : 1, because status 2  
|          7 |                      5 |      3 | 02   | // 02 : 2, at this point the calculation works because status 3
+------------+------------------------+--------+------+

我试过这样的查询

SELECT id, count(id) from sample group by `id`

但结果如下

+------+--------------+
| id   | count        |
+------+--------------+
| 01   |      7       |     
| 02   |      6       |
+------+--------------+

我知道我必须在CASE中使用count函数,但我不知道如何使用我的复杂表格。

mysql sql database
2个回答
2
投票

你想要一个有条件的count(distinct)。我想这就是你想要的:

select id, count(distinct case when status = 3 then id_laporan end)
from sample
group by id;

这计算每个id_laporan的状态为“3”的不同id的数量。

编辑:

SQL表表示无序集。您的结果取决于排序,但您没有指定排序的列。您必须有一个。如有必要,您可以在表中添加一个:

alter table add t_id int auto_increment;

但最终的排序可能不是你真正想要的。

使用这样的列,您可以轻松计算每个id的累计“3”秒数。这是一个使用相关子查询的方法:

select t.*,
       (select count(*)
        from t t2
        where t2.id = t.id and
              t2.? <= t.? and status = 3
       ) 
from t; 

?代表订购的列。如果您有一组带有排序的列,那么也可以使用它。


0
投票

我得到了答案,感谢Gordon Linoff和Paul Spiegel在DISTINCT函数中的CASECOUNT(),我真的很感激(y)

我知道这段代码还有一个错误,但至少它有助于我自己即兴发布这个答案

SELECT t1.id , sum(tot) from ( 
  SELECT id, id_laporan, id_laporan_rekomendasi, 
  COUNT(distinct case when status = 3 then 1 end) as tot
  FROM sample t1
GROUP by id_laporan_rekomendasi ) t1
GROUP BY t1.id

结果

| id | sum(tot) |
|----|----------|
| 01 |        1 |
| 02 |        2 |

这是SQLFiddle Demo

© www.soinside.com 2019 - 2024. All rights reserved.