在 MySQL 中一次汇总多个列
Summarise multiple columns at once in MySQL
我有一些数据(约 70,000 行)的格式与以下类似。
+-----------+-----+-----+----+-----------+
| ID | A | B | C | Whatever |
+-----------+-----+-----+----+-----------+
| 1banana | 42 | 0 | 2 | Um |
| fhqwhgads | 514 | 6 | 9 | Nevermind |
| 2banana | 69 | 42 | 0 | NULL |
| pears | 18 | 96 | 2 | 8.8 |
| zubat2 | 96 | 2 | 14 | "NULL" |
+-----------+-----+-----+----+-----------+
我想输出 table 来计算每个数字在三列中出现的次数,例如:
+--------+---------+---------+---------+-----+
| Number | A count | B count | C count | sum |
+--------+---------+---------+---------+-----+
| 0 | 0 | 1 | 1 | 2 |
| 2 | 0 | 1 | 2 | 3 |
| 6 | 0 | 1 | 0 | 1 |
| 9 | 0 | 0 | 1 | 1 |
| 14 | 0 | 0 | 1 | 1 |
| 18 | 1 | 0 | 0 | 1 |
| 42 | 1 | 1 | 0 | 2 |
| 69 | 1 | 0 | 0 | 1 |
| 96 | 1 | 1 | 0 | 2 |
| 514 | 1 | 0 | 0 | 1 |
+--------+---------+---------+---------+-----+
(在我的实际使用中,输入 table 中的行数至少是查询结果中的行数的 10 倍)
查询 returns 是否在这 3 列中没有任何位置的数字的一行零并不重要,因为缺少不同的总和列(尽管我的偏好是它确实有总和列,不在任何列中的数字都被排除在外)。
目前,我正在使用以下查询来获取未分组的数据:
SELECT * #Number, COUNT(DISTINCT A), COUNT(DISTINCT B), COUNT(DISTINCT C)
FROM
( # Generate a list of numbers to try
SELECT @ROW := @ROW + 1 AS `Number`
FROM DataTable t
join (SELECT @ROW := -9) t2
LIMIT 777 # None of the numbers I am interested in should be greater than this
) AS NumberList
INNER JOIN DataTable ON
Number = A
OR Number = B
OR Number = C
#WHERE <filters on DataTable columns to speed things up>
#WHERE NUMBER = 10 # speed things up
#GROUP BY Number
上面的查询,代码的注释部分保持原样 returns 一个 table 类似于数据 table,但按条目的编号排序它匹配。我想将所有以相同 Number
开头的行组合在一起,并将查询结果的 "data" 列中的值作为 Number
在DataTable
.
对应的列
当我取消注释分组语句(并从 SELECT
语句中删除 *
时),我可以计算每个 Number
出现的行数(对所需输出的 sum
列)。但是,它并没有告诉我 Number
与每个数据列匹配的实际总数:我只得到了找到 Number
的行数的三个副本。 如何根据每个实际列而不是匹配行的总数进行分组?
此外,您可能已经注意到我有一些关于加快速度的评论。此查询 慢 ,因此我添加了几个过滤器以便更快地测试它 运行。我非常希望有一些方法可以使它 运行 变快,以便将查询结果从完整的集合发送到新的 table 并不是重新使用这些数据的唯一合理方法,因为出于非性能原因,我希望能够使用 DataTable
上的过滤器。 是否有更好的方法来构造整个查询以使其 运行 更快?
我想你想使用 union all
进行反透视,然后进行聚合:
select number, sum(a) as a, sum(b) as b, sum(c) as c, count(*) as `sum`
from ((select a as number, 1 as a, 0 as b, 0 as c from t
) union all
(select b, 0 as a, 1 as b, 0 as c from t
) union all
(select c, 0 as a, 0 as b, 1 as c from t
)
) abc
group by number
order by number;
我有一些数据(约 70,000 行)的格式与以下类似。
+-----------+-----+-----+----+-----------+
| ID | A | B | C | Whatever |
+-----------+-----+-----+----+-----------+
| 1banana | 42 | 0 | 2 | Um |
| fhqwhgads | 514 | 6 | 9 | Nevermind |
| 2banana | 69 | 42 | 0 | NULL |
| pears | 18 | 96 | 2 | 8.8 |
| zubat2 | 96 | 2 | 14 | "NULL" |
+-----------+-----+-----+----+-----------+
我想输出 table 来计算每个数字在三列中出现的次数,例如:
+--------+---------+---------+---------+-----+
| Number | A count | B count | C count | sum |
+--------+---------+---------+---------+-----+
| 0 | 0 | 1 | 1 | 2 |
| 2 | 0 | 1 | 2 | 3 |
| 6 | 0 | 1 | 0 | 1 |
| 9 | 0 | 0 | 1 | 1 |
| 14 | 0 | 0 | 1 | 1 |
| 18 | 1 | 0 | 0 | 1 |
| 42 | 1 | 1 | 0 | 2 |
| 69 | 1 | 0 | 0 | 1 |
| 96 | 1 | 1 | 0 | 2 |
| 514 | 1 | 0 | 0 | 1 |
+--------+---------+---------+---------+-----+
(在我的实际使用中,输入 table 中的行数至少是查询结果中的行数的 10 倍)
查询 returns 是否在这 3 列中没有任何位置的数字的一行零并不重要,因为缺少不同的总和列(尽管我的偏好是它确实有总和列,不在任何列中的数字都被排除在外)。
目前,我正在使用以下查询来获取未分组的数据:
SELECT * #Number, COUNT(DISTINCT A), COUNT(DISTINCT B), COUNT(DISTINCT C)
FROM
( # Generate a list of numbers to try
SELECT @ROW := @ROW + 1 AS `Number`
FROM DataTable t
join (SELECT @ROW := -9) t2
LIMIT 777 # None of the numbers I am interested in should be greater than this
) AS NumberList
INNER JOIN DataTable ON
Number = A
OR Number = B
OR Number = C
#WHERE <filters on DataTable columns to speed things up>
#WHERE NUMBER = 10 # speed things up
#GROUP BY Number
上面的查询,代码的注释部分保持原样 returns 一个 table 类似于数据 table,但按条目的编号排序它匹配。我想将所有以相同 Number
开头的行组合在一起,并将查询结果的 "data" 列中的值作为 Number
在DataTable
.
当我取消注释分组语句(并从 SELECT
语句中删除 *
时),我可以计算每个 Number
出现的行数(对所需输出的 sum
列)。但是,它并没有告诉我 Number
与每个数据列匹配的实际总数:我只得到了找到 Number
的行数的三个副本。 如何根据每个实际列而不是匹配行的总数进行分组?
此外,您可能已经注意到我有一些关于加快速度的评论。此查询 慢 ,因此我添加了几个过滤器以便更快地测试它 运行。我非常希望有一些方法可以使它 运行 变快,以便将查询结果从完整的集合发送到新的 table 并不是重新使用这些数据的唯一合理方法,因为出于非性能原因,我希望能够使用 DataTable
上的过滤器。 是否有更好的方法来构造整个查询以使其 运行 更快?
我想你想使用 union all
进行反透视,然后进行聚合:
select number, sum(a) as a, sum(b) as b, sum(c) as c, count(*) as `sum`
from ((select a as number, 1 as a, 0 as b, 0 as c from t
) union all
(select b, 0 as a, 1 as b, 0 as c from t
) union all
(select c, 0 as a, 0 as b, 1 as c from t
)
) abc
group by number
order by number;