在2个表中获取COUNT()和COUNT(DISTINCT())值

时间:2016-02-01 21:36:49

标签: mysql

我正在尝试从已连接的表中获取COUNT(*)"表2"日期是常见的加上来自"表1和#34;的COUNT(DISTINCT(CID))并按普通年月分组:

Table1
---------------
cid |  date   | 
----|---------|
321 | 2016-01 |
----|---------|
423 | 2016-01 |
----|---------|
324 | 2016-01 |
----|---------|
546 | 2015-12 |
----|---------|

Table2
---------------
id  | dateEnq | 
----|---------|
3   | 2016-01 |
----|---------|
6   | 2016-01 |
----|---------|
24  | 2015-12 |
----|---------|
36  | 2015-12 |
----|---------|

MySQL查询:

SELECT COUNT( DISTINCT (t1.cid) ) AS users,
SUBSTR(DATE(t1.date),1,7) AS month,
COUNT(t2.dateEnq) AS enquiries
FROM table1 t1
INNER JOIN table2 t2 ON SUBSTR(t2.dateEnq, 1, 7 ) = SUBSTR(t1.date, 1, 7 )
GROUP BY SUBSTR(DATE(t1.date),1,7)

这是我得到的结果,但查询值是错误的,我认为它不计算Table2中的值,它们应该是每行3,10,25。

如何从表2中获得每月计数?

users | month    | enquiries|
------|----------|-----------
7237  | 2015-10  | 8374     |
12597 | 2015-11  | 30066    |
12980 | 2015-12  | 15514    |
11305 | 2016-01  | 128169   |

1 个答案:

答案 0 :(得分:2)

你的“计数”被夸大了,因为它是一个部分交叉产品。对于给定的月份,t1中的每一行都与t2中同一个月的每一行匹配。

一种选择是在进行连接之前获取计数。例如,使用内联视图:

SELECT c1.users
     , c1.month
     , c2.enquiries
  FROM ( SELECT COUNT(DISTINCT t1.cid)    AS `users`
              , SUBSTR(DATE(t1.date),1,7) AS `month`
           FROM table1 t1
          GROUP BY SUBSTR(DATE(t1.date),1,7)
       ) c1
  JOIN ( SELECT COUNT(t2.dateEnq)         AS `enquiries`
              , SUBSTR(DATE(t2.date),1,7) AS `month`
           FROM table2 t2 
          GROUP BY SUBSTR(DATE(t2.date),1,7)
       ) c2
    ON c2.month = c1.month
 ORDER BY c1.month

这不是获得此结果的唯一方式(甚至是最好的方法)。还有其他查询模式可以获得相同的结果。

如果给定enquiries有可能为零month,那么为了获得返回的零计数,我们可以调整该查询,使其成为外连接,然后替换任何NULL值(对于缺少的行)在外部查询中为零:

SELECT c1.users
     , c1.month
     , IFNULL(c2.enquiries,0) AS `enquiries`
  FROM ( SELECT COUNT(DISTINCT t1.cid)    AS `users`
              , SUBSTR(DATE(t1.date),1,7) AS `month`
           FROM table1 t1
          GROUP BY SUBSTR(DATE(t1.date),1,7)
       ) c1
  LEFT
  JOIN ( SELECT COUNT(t2.dateEnq)         AS `enquiries`
              , SUBSTR(DATE(t2.date),1,7) AS `month`
           FROM table2 t2 
          GROUP BY SUBSTR(DATE(t2.date),1,7)
       ) c2
    ON c2.month = c1.month
 ORDER BY c1.month