MySQL子查询的性能解决方案

时间:2017-05-30 11:43:36

标签: mysql performance subquery

我有两张如下表:

表媒体:

+---------------------------------------------------------+
| media_id | media_name  | media_category  | media_status |
+---------------------------------------------------------+
| 1        | item1       | 2               | true         |
| 2        | item2       | 2               | true         |
| 3        | item3       | 1               | false        |
| 4        | item3       | 1               | false        |
| 5        | item3       | 1               | true         |
+---------------------------------------------------------+

表类别:

+--------------------+ 
| cat_id | cat_name  | 
+--------------------+ 
| 1      | blue      | 
| 2      | red       | 
| 3      | white     | 
| 4      | green     | 
+--------------------+

我希望按状态检索所有类别的相关媒体数量。

所以在我的例子中,结果必须是:

+--------------------------------------------------------------------------------+ 
| cat_id | cat_name  | countMediaTotal | countMediaActive  | countMediaInactive  |
+--------------------------------------------------------------------------------+ 
| 1      | blue      | 3               | 1                 | 2                   |
| 2      | red       | 2               | 2                 | 0                   |
| 3      | white     | 0               | 0                 | 0                   |
| 4      | green     | 0               | 0                 | 0                   |
+--------------------------------------------------------------------------------+ 

我的实际SQL请求:

SELECT *,   
(SELECT COUNT(*) FROM media AS MED WHERE CAT.cat_id = MED.media_category) AS countMediaTotal, 
(SELECT COUNT(*) FROM media AS MED WHERE CAT.cat_id = MED.media_category AND media_status = 'true') AS countMediaActive, 
(SELECT COUNT(*) FROM media AS MED WHERE CAT.cat_id = MED.media_category AND media_status = 'false') AS countMediaInactive 
FROM `category` AS CAT 

有3个类似的子查询。

是否有更强大的解决方案来实现这一目标还是最好的?

2 个答案:

答案 0 :(得分:1)

你可以这样做:

SELECT c.cat_id, c.cat_name,   
COUNT(*) AS countMediaTotal, 
SUM(IF(m.media_status = 'true', 1, 0)) AS countMediaActive, 
SUM(IF(m.media_status = 'false', 1, 0)) AS countMediaInactive 
FROM `category` AS c
LEFT JOIN media m ON m.media_category = c.cat_id
GROUP BY c.cat_id, c.cat_name

答案 1 :(得分:0)

我会做这样的事......

SELECT c.*
     , COALESCE(m.media_status,0) media_status
     , COUNT(0) total 
  FROM category c 
  LEFT 
  JOIN media m 
    ON c.cat_id = m.media_category 
 GROUP 
    BY c.cat_id
     , m.media_status;

...并处理应用程序代码中的任何剩余显示问题。