【问题标题】:Count with case not giving correct results计算没有给出正确结果的情况
【发布时间】:2018-03-16 03:28:34
【问题描述】:

我正在使用query 来生成计数。以下是我的查询

SELECT COUNT(DISTINCT sur.`customer_id`) AS 'Survey Done'
 ,COUNT(CASE WHEN sn.operator_name LIKE '%Zong%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE NULL END) AS 'Zong No Signal'
 ,COUNT(CASE WHEN sn.operator_name LIKE '%Mobilink%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE NULL END) AS 'Mobilink No Signal'
 ,COUNT(CASE WHEN sn.operator_name LIKE '%Ufone%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE NULL END) AS 'Ufone No Signal'
 ,COUNT(CASE WHEN sn.operator_name LIKE '%Telenor%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE NULL END) AS 'Telenor No Signal'
 ,COUNT(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE NULL END) AS 'Wall'
 ,COUNT(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE NULL END) AS 'PC Pole'
 ,COUNT(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE NULL END) AS 'Structure pole'
 ,COUNT(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE NULL END) AS 'Spon pole'
 ,sd.`sub_div_code` AS 'SD Code',  
 sd.`name` AS 'SD Name', 
 sd.`circle_name` AS 'Circle Name', 
 sd.`division_name` AS 'Division Name'
 FROM `survey` sur 
 INNER JOIN `survey_hesco_subdivision` sd ON sur.`sub_division` = 
 sd.`sub_div_code`
 INNER JOIN `survey_networks` sn ON sur.`id` = sn.`survey_id`
 WHERE sur.`customer_id` IN ('37010185878',
'37010718785',
'37010718759',
'37010357911',
'37010673539',
'37010673796',
'37010672166',
'37010672162')
 GROUP BY sd.`name`

所有计数都正确,但以下部分的值不正确

,COUNT(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE NULL END) AS 'Wall'
,COUNT(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE NULL END) AS 'PC Pole'
,COUNT(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE NULL END) AS 'Structure pole'
,COUNT(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE NULL END) AS 'Spon pole'

他们的输出是10,4,240。但实际计数为4,1,70

样本输出为

最后一个值spon pole0 对于某些记录但不是所有记录,因此它的计数也不正确。

如何获得这些值的正确计数?我也尝试过= 登录替换LIKE,但它仍然不会给我正确的结果。我也看过这个solution

任何帮助将不胜感激

【问题讨论】:

  • 如果你把你的 SQL 放到 Sqlfiddle.com 中,你有更好的机会得到一个好的答案。结构和一些示例数据,以及预期的结果。
  • 您能否提供一些真正有用的示例数据
  • @BrianHoover 你可以看一下here,但结果是正确的,因为我只添加了pol_type 部分。 Sqlfiddle 不允许我扩展架构,因为它给了我一个错误。
  • @D-Shih 我已经在问题中添加了输出
  • 在没有看到所有数据的情况下,我的假设是您的表中的 INNER JOIN 为每个调查创建了多行,因此您计算pole_type 的次数比您预期的要多。您必须执行 COUNT DISTINCT 才能获得正确数量的调查,这一事实似乎表明情况确实如此。

标签: mysql sql count case


【解决方案1】:

您可以使用SUM 代替CountELSE 设置0

SELECT COUNT(DISTINCT sur.`customer_id`) AS 'Survey Done'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE 0 END) AS 'Wall'
,SUM(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE 0 END) AS 'PC Pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE 0 END) AS 'Structure pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE 0 END) AS 'Spon pole'
,sur.`sub_division`
FROM `survey` sur 

如果您想在sur.sub_division 上进行区分,只需添加group by by sur.sub_division

SELECT COUNT(DISTINCT sur.`customer_id`) AS 'Survey Done'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE 0 END) AS 'Wall'
,SUM(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE 0 END) AS 'PC Pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE 0 END) AS 'Structure pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE 0 END) AS 'Spon pole'
,sur.`sub_division`
FROM `survey` sur 
GROUP BY sur.`sub_division`

编辑

我想问题出在Group by filed 你可以试试这个。

SELECT COUNT(DISTINCT sur.`customer_id`) AS 'Survey Done'
     ,SUM(CASE WHEN sn.operator_name LIKE '%Zong%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Zong No Signal'
     ,SUM(CASE WHEN sn.operator_name LIKE '%Mobilink%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Mobilink No Signal'
     ,SUM(CASE WHEN sn.operator_name LIKE '%Ufone%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Ufone No Signal'
     ,SUM(CASE WHEN sn.operator_name LIKE '%Telenor%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Telenor No Signal'
     ,SUM(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE 0 END) AS 'Wall'
     ,SUM(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE 0 END) AS 'PC Pole'
     ,SUM(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE 0 END) AS 'Structure pole'
     ,SUM(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE 0 END) AS 'Spon pole'
     ,sd.`sub_div_code` AS 'SD Code',  
     sd.`name` AS 'SD Name', 
     sd.`circle_name` AS 'Circle Name', 
     sd.`division_name` AS 'Division Name'
 FROM `survey` sur 
 INNER JOIN `survey_hesco_subdivision` sd ON sur.`sub_division` = 
 sd.`sub_div_code`
 INNER JOIN `survey_networks` sn ON sur.`id` = sn.`survey_id`
 WHERE sur.`customer_id` IN 
 ('37010185878',
'37010718785',
'37010718759',
'37010357911',
'37010673539',
'37010673796',
'37010672166',
'37010672162')
 GROUP BY 
     sd.`sub_div_code`, 
     sd.`name`,
     sd.`circle_name`, 
     sd.`division_name`

SQLFiddle

【讨论】:

  • 我会尽力让你知道 :)
  • 尝试了你的建议,但我的计数仍然不正确
  • @MrFaisal 链接sqlfiddle.com/#!9/59132/16 与您的样本数据是否正确?
  • 我猜问题出在Group by 归档,你可以试试我的编辑答案。
  • 您能提供survey ,survey_hesco_subdivision ,survey_networks 表的架构和少量样本数据吗?因为那里有一个连接表。
【解决方案2】:

所以,经过大量搜索,我能够找出正确的查询,这给了我正确的结果

SELECT SUM(z.Survey_Done) AS 'Survey Done',SUM(Zong) AS 'Zong No Signal',SUM(Mobilink) AS 'Mobilink No Signal',SUM(Ufone) AS 'Ufone No Signal',SUM(Telenor) AS 'Telenor No Signal'
,SUM(Wall) AS Wall,SUM(PC_Pole) AS 'PC Pole',SUM(Structure_pole) AS 'Structure Pole',SUM(Spon_pole) AS 'Spon Pole',SDCode
,sd.`name` AS 'SD Name' 
,sd.`circle_name` AS 'Circle Name'
,sd.`division_name` AS 'Division Name'
FROM (
SELECT COUNT(DISTINCT sur.`customer_id`) AS 'Survey_Done',
0 AS 'Zong',
0 AS 'Mobilink',
0 AS 'Ufone',
0 AS 'Telenor'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Wall%' THEN 1 ELSE 0 END) AS 'Wall'
,SUM(CASE WHEN sur.`pole_type` LIKE '%PC Pole%' THEN 1 ELSE 0 END) AS 'PC_Pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Structure Pole%' THEN 1 ELSE 0 END) AS 'Structure_pole'
,SUM(CASE WHEN sur.`pole_type` LIKE '%Spon pole%' THEN 1 ELSE 0 END) AS 'Spon_pole'
,sd.`sub_div_code` AS 'SDCode'

FROM `survey` sur 
INNER JOIN `survey_hesco_subdivision` sd ON sur.`sub_division` = 
sd.`sub_div_code`

WHERE sur.`customer_id` IN ()
GROUP BY sd.`sub_div_code`, sd.`name`, sd.`circle_name`, sd.`division_name`
UNION

SELECT 
0 AS 'Survey_Done',
SUM(CASE WHEN sn.operator_name LIKE '%Zong%' AND sn.`signal_strength` = 'No 
Signal' THEN 1 ELSE 0 END) AS 'Zong'
,SUM(CASE WHEN sn.operator_name LIKE '%Mobilink%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Mobilink'
,SUM(CASE WHEN sn.operator_name LIKE '%Ufone%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Ufone'
,SUM(CASE WHEN sn.operator_name LIKE '%Telenor%' AND sn.`signal_strength` = 'No Signal' THEN 1 ELSE 0 END) AS 'Telenor'
,0 AS 'Wall'
,0 AS 'PC Pole'
,0 AS 'Structure pole'
,0 AS 'Spon pole'
,sd.`sub_div_code` AS 'SDCode'
FROM  `survey_networks` sn 
INNER JOIN `survey` sur ON sur.`id` = sn.`survey_id`
INNER JOIN `survey_hesco_subdivision` sd ON sur.`sub_division` = 
sd.`sub_div_code`

WHERE sur.`customer_id` IN ()
GROUP BY sd.`sub_div_code`
) z
INNER JOIN `survey_hesco_subdivision` sd ON sd.`sub_div_code`=SDCode
GROUP BY sd.`name`

我在上述查询中使用了UNION

【讨论】:

  • 感谢您的回答
猜你喜欢
  • 2014-09-12
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-01
  • 1970-01-01
相关资源
最近更新 更多