在mysql中,它没有显示计数值0

时间:2016-05-21 06:18:03

标签: mysql sql

SELECT IF(COUNT(cm.CUSTOMER_ID)>0,COUNT(cm.CUSTOMER_ID),0) COUNT
FROM  customer_master cm
JOIN customer_issue_details ci USING (customer_id)
WHERE ci.ACTUAL_DATE_RETURN < ci.RETURN_DATE
   AND CUSTOMER_NAME LIKE 'r%'
GROUP BY cm.`CUSTOMER_ID`;

当没有找到这样的记录时,它不会在计数下显示0但仅显示别名计数。如何得到0计数。我使用ifnull,ifisnull也没用。 请任何人都可以告诉为什么这不起作用以及如何获得0。

2 个答案:

答案 0 :(得分:2)

您需要使用LEFT JOIN。并且任何ci列的每个条件都必须在ON子句中(否则LEFT JOIN将转换为INNER JOIN)。而且您必须将ci.CUSTOMER_ID计算为cm.CUSTOMER_ID

SELECT cm.CUSTOMER_ID, COUNT(ci.CUSTOMER_ID) COUNT
FROM  customer_master cm
LEFT JOIN customer_issue_details ci
  ON  ci.customer_id = cm.CUSTOMER_ID
  AND ci.ACTUAL_DATE_RETURN < ci.RETURN_DATE
WHERE CUSTOMER_NAME LIKE 'r%'
GROUP BY cm.`CUSTOMER_ID`;

INNER JOIN(JOIN是INNER JOIN的别名)将过滤掉cm表中的任何行,如果找不到ci表中与JOIN条件匹配的行(它不是如果您使用USINGON,则无关紧要。 LEFT JOIN将从cm表返回至少一行,但如果找不到与ci表匹配JOIN条件的行,则ci表中的所有列都将为NULL。< / p>

示例:

cm:
| customer_id |
|-------------|
|           1 |
|           2 |
|           3 |

ci:

| customer_id | 
|-------------|
|           1 |
|           1 |
|           2 |

INNER JOIN:

SELECT cm.customer_id as `cm.customer_id`, ci.customer_id as `ci.customer_id`
FROM cm
JOIN ci 
  ON ci.customer_id = cm.customer_id;

| customer_id | customer_id |
|-------------|-------------|
|           1 |           1 |
|           1 |           1 |
|           2 |           2 |

LEFT JOIN:

SELECT cm.customer_id, ci.customer_id
FROM cm
LEFT JOIN ci 
  ON ci.customer_id = cm.customer_id;

| customer_id | customer_id |
|-------------|-------------|
|           1 |           1 |
|           1 |           1 |
|           2 |           2 |
|           3 |      (null) |

fiddle

使用GROUP BY cm.customer_idCOUNT(ci.customer_id),您可以计算每个cm.customer_id找到的行数。

SELECT cm.customer_id, COUNT(ci.customer_id)
FROM cm
LEFT JOIN ci 
  ON ci.customer_id = cm.customer_id
GROUP BY cm.customer_id

| customer_id | COUNT(ci.customer_id) |
|-------------|-----------------------|
|           1 |                     2 |
|           2 |                     1 |
|           3 |                     0 |

fiddle

它为0返回cm.customer_id = 3,因为COUNT只计算非NULL的值。

如果您使用COUNT(cm.customer_id),则1会获得cm.customer_id = 3,因为它不是NULL。 fiddle

现在,如果ci表中的列有任何条件(如ci.customer_id < 2),并且将它放在WHERE子句中,则将过滤掉与该条件不匹配的所有行。 / p>

SELECT cm.customer_id, ci.customer_id
FROM cm
LEFT JOIN ci 
  ON  ci.customer_id = cm.customer_id
WHERE ci.customer_id < 2

| customer_id | customer_id |
|-------------|-------------|
|           1 |           1 |
|           1 |           1 |

但是将该条件移到LEFT JOIN ON子句中,每个cm.customer_id至少保留一行,因为这是LEFT JOIN的工作方式。

SELECT cm.customer_id, ci.customer_id
FROM cm
LEFT JOIN ci 
  ON  ci.customer_id = cm.customer_id
  AND ci.customer_id < 2

| customer_id | customer_id |
|-------------|-------------|
|           1 |           1 |
|           1 |           1 |
|           2 |      (null) |
|           3 |      (null) |

现在GROUP BYCOUNT

SELECT cm.customer_id, COUNT(ci.customer_id)
FROM cm
LEFT JOIN ci 
  ON  ci.customer_id = cm.customer_id
  AND ci.customer_id < 2
GROUP BY cm.customer_id;

| customer_id | COUNT(ci.customer_id) |
|-------------|-----------------------|
|           1 |                     2 |
|           2 |                     0 |
|           3 |                     0 |

sqlfiddle

答案 1 :(得分:0)

如果不进行测试,请尝试不使用cm.CUSTOMER_ID而是使用ci.CUSTOMER_ID进行分组。另外,我认为您需要LEFT JOIN

SELECT COUNT(ci.CUSTOMER_ID)
FROM customer_master cm
LEFT JOIN customer_issue_details ci USING (customer_id)
WHERE ci.ACTUAL_DATE_RETURN < ci.RETURN_DATE
   AND CUSTOMER_NAME LIKE 'r%'
GROUP BY ci.CUSTOMER_ID;

以下是没有ACTUAL_DATE_RETURN且没有RETURN_DATE的简化的SQL Fiddle:http://sqlfiddle.com/#!9/73cc64/2/0

更新1

  

如果你改变&#39;%r&#39;到&#39;%a&#39;它甚至没有显示输出表,但它应该在你的表名

下给出0

这就是SQL的工作原理。由于没有名称与该表达式匹配的客户,因此您不会获得结果行。您需要检查应用程序中设置的空结果。