我正在尝试在一个查询中组合多个选择以尽可能少地使用数据。 我有这个sql表(例子)
id category status
1 test1 A
2 test2 B
3 test1 A
4 test3 B
5 test1 C
首先,我想选择具有相同类别的行数。
SELECT category, COUNT(category) FROM test GROUP BY category
然后我想计算每个类别的状态。我会用这个查询来做这件事。
SELECT status, COUNT(status) FROM test WHERE category = 'test1' GROUP BY STATUS
所以我想要一个包含总数的列,然后是每个类别的状态数。 我能以某种方式结合这些吗?这是可能的,还是我必须意识到我必须多次获取数据以获得正确的结果?
答案 0 :(得分:4)
您可以尝试GROUP BY
类别和状态,并使用WITH ROLLUP
获取汇总值:
SELECT category, status, count(*)
FROM test
GROUP BY category, status WITH ROLLUP
结果如下:
category | status | count(*)
----------+--------+----------
test1 | A | 2
test1 | C | 1
test1 | NULL | 3
test2 | B | 1
test2 | NULL | 1
test3 | B | 1
test3 | NULL | 1
NULL | NULL | 5
如果忽略包含NULL
的行,则其余为常规GROUP BY category, status
。有2个条目有category = 'test1' AND status = 'A'
,有一个条目有category = 'test1' AND status = 'C'
,依此类推。
结果的第三行(category = 'test1', status = NULL, count(*) = 3
)汇总了category = 'test1'
的行。无论count(*)
列中的值是多少,它都会为category = 'test1'
的所有行计算status
。以类似的方式计算category = 'test2'
和category = 'test3'
的摘要行。
最后一行是整个表的摘要。 count(*) = 5
包含所有行,无论它们在category
和status
列中具有什么价值。
答案 1 :(得分:1)
您可以像这样一次对所有类别运行第二个查询:
mysql> select category, status, count(*) from foo group by category, status;
+----------+--------+----------+
| category | status | count(*) |
+----------+--------+----------+
| test1 | A | 2 |
| test1 | C | 1 |
| test2 | B | 1 |
| test3 | B | 1 |
+----------+--------+----------+
4 rows in set (0.39 sec)
然后,您可以通过汇总其所有行来计算类别范围的计数。如果你真的想要它也是同一个查询的一部分,你可以这样做:
mysql> select foo.category, status, count(*), cat_count
-> from foo
-> inner join (select category, count(*) cat_count from foo group by category) x
-> on x.category = foo.category
-> group by foo.category, status;
+----------+--------+----------+-----------+
| category | status | count(*) | cat_count |
+----------+--------+----------+-----------+
| test1 | A | 2 | 3 |
| test1 | C | 1 | 3 |
| test2 | B | 1 | 1 |
| test3 | B | 1 | 1 |
+----------+--------+----------+-----------+
4 rows in set (0.00 sec)
答案 2 :(得分:0)
不幸的是,MySQL不支持窗口函数。
一种方法是在一个查询中获取每个类别的状态计数:
SELECT
category,
status,
COUNT(*) AS status_count
FROM
test
GROUP BY
category, status
然后INNER JOIN
有关类别计数的信息:
SELECT
a.*, b.category_count
FROM (
SELECT
category,
status,
COUNT(*) AS status_count
FROM
test
GROUP BY
category, status
) a
INNER JOIN ( SELECT category, COUNT(*) AS category_count FROM test GROUP BY category ) b ON
a.category = b.category