MYSQL:两个计数,一组...更好的方法?

时间:2014-03-19 08:34:28

标签: mysql sql performance

我有一张看起来像这样的桌子......

*------------------------------------*
|  id  |  state  |  name  |  status  |
|------|---------|--------|----------|
|  1   |   AZ    |  Tim   |   OK     |
|  2   |   AZ    |  Jon   |   BAD    |
|  3   |   NV    |  Bob   |   BAD    |
|  4   |   NV    |  Ted   |   OK     |
|  5   |   NV    |  Don   |   BAD    |
|  6   |   CO    |  Guy   |   OK     |
|  7   |   CO    |  Jed   |   OK     |
|  8   |   CA    |  Cal   |   BAD    |
|  9   |   CA    |  Tom   |   OK     |
|  10  |   CA    |  Ian   |   OK     |
*------------------------------------*

我需要产生一个看起来像这样的结果......

*--------------------------------*
|  state  | total  |  totalgood  |
|---------|--------|-------------|
|   AZ    |  2     |   1         |
|   NV    |  3     |   1         |
|   CO    |  2     |   2         |
|   CA    |  3     |   2         |
*--------------------------------*

我可以这样做......

SELECT state AS state, 
  COUNT(*) AS total, 
  SUM(CASE WHEN status = 'OK' THEN 1 ELSE 0 END) AS totalgood
FROM mytable 
WHERE state IN ('AZ','NV','CO','CA') 
GROUP BY state;

我担心的是这是一张非常大的桌子,有超过100k的记录。我的理解是使用SUM会导致它在计数时循环遍历每一行。这可能是一个非常大的性能影响。

那么有更好的方法吗?或者......我的担忧是没有根据的?我意识到我并不像我一样精通MySQL,而且我很难在JOIN周围思考。所以任何建议都表示赞赏。

(*请注意,WHERE子句虽然不是必需的,但仍适用于我的实际应用。)

2 个答案:

答案 0 :(得分:2)

对我来说很好看。如果您担心使用SUM,可以轻松将其转换为COUNT:

COUNT(CASE WHEN status = 'OK' THEN 1 ELSE NULL END) AS totalgood

BTW:不再认为100k行是大的。

答案 1 :(得分:0)

尝试在分组依据中使用WITH ROLLUP-Function

DOC