每列的MySQL COUNT值

时间:2016-05-20 17:45:15

标签: mysql sql

我正在试图弄清楚如何计算多个列中的值。 似乎我做的第一个COUNT给了我正确的结果,但是我试图获得第二列计数的所有内容都给出了错误的结果。 例如,使用以下两列

  
Q2 Q3  
1   1  
1   1  
2   2  
1   1  
1   1  
5   5  
3   5  
5   3  
4   1  
2   2  
3   3  
3   3  
5   5  
3   3  
2   1  
2   1  
3   2  
4   1  
1   1  
1   1  
2   2  
5   5  
3   3  
2   1  
3   3  
1   1  
2   1  
SELECT COUNT(Q2) AS QU2 FROM mytable GROUP BY Q2
QU2 = 7 7 7 2 4

给了我第二季的计数。 7个人,7个人,等等......

然而,以下给出了意想不到的结果。

SELECT COUNT(Q2) AS QU2, COUNT(Q3) AS QU3 FROM mytable GROUP BY Q2, Q3

  7 4 3 1 5 1 2 1 3

我认为它与GROUP BY有关,但我不知道如何绕过它以获得所需的结果 所以我想要得到

的结果
QU2 = 7 7 7 2 4
QU3 = 13 4 6 4  

QU2 QU3
7   13
7   4
7   6 
2   4
4
对于QU4 QU5,等等......我将不胜感激任何帮助 谢谢

4 个答案:

答案 0 :(得分:0)

我认为您需要取消数据的转移。在这种情况下,这只意味着由group by连接的多个union all

select 'q2' as which, q2, count(*) as cnt
from mytable
group by q2
union all
select 'q3' as which, q3, count(*) as cnt
from mytable
group by q3;

您可以根据需要添加更多子查询。

注意:这会将值放在单独的行中,而不是放在单独的列中。

答案 1 :(得分:0)

我认为这会让你最接近你想要的。您可以使用生成数字1的任何方法将数字表替换为Q2或Q3中的最大值。

CREATE TABLE dbo.Numbers (num INT)
INSERT INTO dbo.Numbers (num) VALUES (1), (2), (3), (4), (5)

SELECT
    N.num,
    SUM(CASE WHEN MT.Q2 = N.num THEN 1 ELSE 0 END) AS QU2,
    SUM(CASE WHEN MT.Q3 = N.num THEN 1 ELSE 0 END) AS QU3
FROM
    dbo.Numbers N
CROSS JOIN dbo.My_Table MT
GROUP BY
    N.num

添加其他列(对于Q4等)只是意味着添加另一个SUM(CASE...)

答案 2 :(得分:0)

GROUP BY如何运作?

让我们谈谈您的第一个查询(我在Q2子句中添加了列SELECT,以使其输出更清晰):

SELECT Q2, COUNT(*) AS QU2
FROM mytable
GROUP BY Q2

首先,如果存在WHERE子句,它将获得与WHERE条件匹配的所有行。因为您的查询没有WHERE子句,所以读取表中的所有行。

在下一步中,上一步中读取的行按照GROUP BY子句中指定的表达式进行分组(假设它只包含一个表达式,如上面的查询所做的那样)。在内部,对行进行分组需要先对它们进行排序。

这是在此步骤中组织数据的方式。我在每组中的行之间添加了水平分隔符,以使所有内容都清晰:

Q2  Q3  
-------
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
-------
 2   1  
 2   1  
 2   1  
 2   1  
 2   2  
 2   2  
 2   2  
-------
 3   2  
 3   3  
 3   3  
 3   3  
 3   3  
 3   3  
 3   5  
-------
 4   1  
 4   1  
-------
 5   3  
 5   5  
 5   5  
 5   5  
-------

在下一步中,每个组创建一行,然后转到生成的结果集。

上面的查询清楚地返回:

Q2  QU2
--------
 1    7
 2    7
 3    7
 4    2
 5    4

GROUP BY子句包含多个表达式时会发生什么?

让我们进行第二次查询(再次,我添加了一些列来显示其行为):

SELECT Q2, Q3, COUNT(*) AS cnt
FROM mytable
GROUP BY Q2, Q3

它的工作方式与上一个查询类似,但由于GROUP BY子句包含两个表达式,因此为Q2的值创建的每个组都会根据{{1}的值在子组中拆分}}。假设在Q3子句中有另一个表达式(让我们说'Q4},为一对GROUP BY创建的每个子组进一步划分为子组,用于所有值(Q2, Q3)等等。

对于您的表格,组和子组如下:

Q4

我使用双线分隔组和较小的单行来分隔每组内的子组。

此查询的输出为:

Q2  Q3  
=======
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
 1   1  
=======
 2   1  
 2   1  
 2   1  
 2   1  
  ---
 2   2  
 2   2  
 2   2  
=======
 3   2  
  ---
 3   3  
 3   3  
 3   3  
 3   3  
 3   3  
  ---
 3   5  
=======
 4   1  
 4   1  
=======
 5   3  
  ---
 5   5  
 5   5  
 5   5  
=======

如何获得所需的结果?

使用单个查询无法获得所需的结果。更重要的是,你建议的结果集没有多大意义。

您可以使用Q2 Q3 cnt ------------ 1 1 7 2 1 4 2 2 3 3 2 1 3 3 5 3 5 1 4 1 2 5 3 1 5 5 3 合并两个查询,以获取所需的数据其他信息,以帮助您了解这些数字的来源:

UNION

输出结果为:

SELECT 'Q2' AS source, Q2 AS q, COUNT(Q2) AS cnt FROM mytable GROUP BY Q2
UNION
SELECT 'Q3' AS source, Q3 AS q, COUNT(Q3) AS cnt FROM mytable GROUP BY Q3

很清楚,不是吗?前5行来自查询 source q cnt ---------------- Q2 1 7 Q2 2 7 Q2 3 7 Q2 4 2 Q2 5 4 Q3 1 13 Q3 2 4 Q3 3 6 Q3 5 4 ,它们在GROUP BY Q2列中的值告诉每个组q的值是多少(Q2次出现7 1}}列1Q2 72 73 2等等) 。最后4行告诉类似的故事4 Q3131,依此类推。)

备注

Q3COUNT(*)之间存在差异:COUNT(Q2)计算组中的行数,COUNT(*)计算列中的非{ - 1}}值COUNT(Q2)。它不关心重复,它只忽略NULL值。如果您想计算不同的值,则必须添加Q2关键字:NULL

答案 3 :(得分:-1)

我认为Asaph走在正确的轨道上,不过我会稍微改变一下select distinct count(Q2) as QU2, count(Q3) as QU3 from myTable;