如何在一组总和中显示0?

时间:2014-04-03 16:52:04

标签: mysql sql

我尝试创建交叉表,但我需要一种通过cia_ensures重复每个policy_business_unit组的查询

我的桌子:

|policies|
  |id|  |client|  |policy_business_unit_id|  |cia_ensure_id|   |state|       
   1      MATT                  1                   1             0
   2      STEVE                 1                   2             1
   3      BILL                  1                   3             2
   4      LARRY                 1                   4             0

|policy_business_units|
   |id|   |name|  |comercial_area_id|
     1     LIFE         1 

|comercial_areas|
   |id|   |name|
    1      BANK

|cia_ensures|
   |id|   |name|
    1      SPRINT
    2      APPLE
    3      PEPSI
    4      ORANGE
    5      BT

以下是信息:

http://sqlfiddle.com/#!2/37690/2

我试图使用所有cia_ensures显示计算:

SELECT ce.name AS CIAS, pb.name AS UNIT,
   SUM(CASE WHEN p.state =0 THEN 1 ELSE 0 END ) AS ACTIVES, 
   SUM(CASE WHEN p.state =1 THEN 1 ELSE 0 END ) AS INACTIVES,
   SUM(CASE WHEN p.state =2 THEN 1 ELSE 0 END ) AS OTHERS
From policies p 
  INNER JOIN policy_business_units pb ON pb.id = p.policy_business_unit_id
  INNER JOIN comercial_areas ca ON ca.id = pb.comercial_area_id
  INNER JOIN cia_ensures ce ON ce.id = p.cia_ensure_id
WHERE policy_business_unit_id IN (1) 
GROUP BY cia_ensure_id

我得到了这个结果:

UNIT             CIAS        COMERCIAL_AREAS    STATE_0   STATE_1   STATUS_2
 LIFE            SPRINT       BANK                  1       0           0
 LIFE            APPLE        BANK                  0       1           0
 LIFE            PEPSI        BANK                  0       0           1
 LIFE            ORANGE       BANK                  1       0           0

这是我的问题: 我想显示所有cia_ensure_id,如果没有关系显示0

如何获得此结果?

UNIT             CIAS        COMERCIAL_AREAS    STATE_0   STATE_1   STATUS_2
 LIFE            SPRINT       BANK                  1       0           0
 LIFE            APPLE        BANK                  0       1           0
 LIFE            PEPSI        BANK                  0       0           1
 LIFE            ORANGE       BANK                  1       0           0
 LIFE            BT           BANK                  0       0           0 

我试过

SELECT ce.name AS CIAS, pb.name AS UNIT,
   SUM(CASE WHEN p.state =0 THEN 1 ELSE 0 END ) AS ACTIVES, 
   SUM(CASE WHEN p.state =1 THEN 1 ELSE 0 END ) AS INACTIVES,
   SUM(CASE WHEN p.state =2 THEN 1 ELSE 0 END ) AS OTHERS
From policies p 
  INNER JOIN policy_business_units pb ON pb.id = p.policy_business_unit_id
  INNER JOIN comercial_areas ca ON ca.id = pb.comercial_area_id
  INNER JOIN cia_ensures ce ON ce.id = p.cia_ensure_id
WHERE policy_business_unit_id IN (1) AND cia_ensured_id IN (1,2,3,4,5)
GROUP BY cia_ensure_id

将接受所有类型的帮助。

请接受各种帮助。

感谢。

1 个答案:

答案 0 :(得分:2)

SELECT ce.name AS CIAS, pb.name AS UNIT,
   SUM(CASE WHEN p.state =0 THEN 1 ELSE 0 END ) AS ACTIVES, 
   SUM(CASE WHEN p.state =1 THEN 1 ELSE 0 END ) AS INACTIVES,
   SUM(CASE WHEN p.state =2 THEN 1 ELSE 0 END ) AS OTHERS
From policies p 
  INNER JOIN policy_business_units pb ON pb.id = p.policy_business_unit_id
  INNER JOIN comercial_areas ca ON ca.id = pb.comercial_area_id
  RIGHT JOIN cia_ensures ce ON ce.id = p.cia_ensure_id
WHERE (policy_business_unit_id IN (1) or policy_business_unit_id is null)
GROUP BY cia_ensure_id

从内到右改变,如果它在其他表之前就可以保留,因为它是最后一个表。基本上你想要来自CIA的所有记录,只有那些在其他表中匹配的记录。

请注意,您还必须在policy_business_Unit上查找空值,否则(1)将排除右连接添加的行。

或者将条件移动到连接,以便它仅应用连接之前的行

SELECT ce.name AS CIAS, pb.name AS UNIT,
   SUM(CASE WHEN p.state =0 THEN 1 ELSE 0 END ) AS ACTIVES, 
   SUM(CASE WHEN p.state =1 THEN 1 ELSE 0 END ) AS INACTIVES,
   SUM(CASE WHEN p.state =2 THEN 1 ELSE 0 END ) AS OTHERS
From policies p 
  INNER JOIN policy_business_units pb 
    ON pb.id = p.policy_business_unit_id 
    and policy_business_unit_id IN (1)
  INNER JOIN comercial_areas ca ON ca.id = pb.comercial_area_id
  RIGHT JOIN cia_ensures ce ON ce.id = p.cia_ensure_id
GROUP BY cia_ensure_id

假设所有NULL PB.names都可以读取'LIFE'然后更改第一个选择行以读取...但这对我来说是一个不好的假设。因此,除非有一个规则来管理这个,否则null应该是基于设计的有效响应。

SELECT ce.name AS CIAS, coalesce(pb.name,'LIFE') AS UNIT,