[英]MySQL - GROUP BY not working with multiple CASE WHEN statements
我正在使用 Kickstarter 数据库开发数据库,我正在尝试:
我的原始代码如下:
SELECT
CASE
WHEN DATEDIFF(campaign.deadline,campaign.launched)<=30 THEN 'Short Campaign'
WHEN DATEDIFF(campaign.deadline,campaign.launched)>30 AND DATEDIFF(campaign.deadline,campaign.launched)<=60 THEN 'Mid-lengthed Campaign'
ELSE 'Long Campaign'
END AS 'Campaign Length',
CASE
WHEN currency.name='GBP' THEN ROUND(SUM(campaign.pledged)*0.80,2)
WHEN currency.name='CAD' THEN ROUND(SUM(campaign.pledged)*1.36)
WHEN currency.name='AUD' THEN ROUND(SUM(campaign.pledged)*1.43)
WHEN currency.name='NOK' THEN ROUND(SUM(campaign.pledged)*9.28)
WHEN currency.name='EUR' THEN ROUND(SUM(campaign.pledged)*0.87)
WHEN currency.name='MXN' THEN ROUND(SUM(campaign.pledged)*22.48)
WHEN currency.name='SEK' THEN ROUND(SUM(campaign.pledged)*0.04)
WHEN currency.name='NZD' THEN ROUND(SUM(campaign.pledged)*1.53)
WHEN currency.name='CHF' THEN ROUND(SUM(campaign.pledged)*0.94)
WHEN currency.name='DKK' THEN ROUND(SUM(campaign.pledged)*6.52)
WHEN currency.name='HKD' THEN ROUND(SUM(campaign.pledged)*7.75)
WHEN currency.name='SGD' THEN ROUND(SUM(campaign.pledged)*1.39)
WHEN currency.name='JPY' THEN ROUND(SUM(campaign.pledged)*107.11)
ELSE ROUND(SUM(campaign.pledged),2)
END AS 'Amount Raised'
FROM campaign
LEFT JOIN currency ON currency.id=campaign.currency_id
GROUP BY `Campaign Length`;
我期待的结果是:
Campaign Length. ---- Amount Raised
Short Campaign. ---- XXXXXXXXXXXXX
Mid-Lengthed Campaign ---- XXXXXXXXXXXXX
Long Campaign. ---- XXXXXXXXXXXXX
其中XXXXXX为折算后的质押金额之和。 原始代码显示:
Error Code: 1055. Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'ks_data.currency.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
所以我通过添加额外的 GROUP BY 即兴创作,在意识到我不能 GROUP BY Amount Raised
之后:
SELECT
CASE
WHEN DATEDIFF(campaign.deadline,campaign.launched)<=30 THEN 'Short Campaign'
WHEN DATEDIFF(campaign.deadline,campaign.launched)>30 AND DATEDIFF(campaign.deadline,campaign.launched)<=60 THEN 'Mid-lengthed Campaign'
ELSE 'Long Campaign'
END AS 'Campaign Length',
CASE
WHEN currency.name='GBP' THEN ROUND(SUM(campaign.pledged)*0.80,2)
WHEN currency.name='CAD' THEN ROUND(SUM(campaign.pledged)*1.36)
WHEN currency.name='AUD' THEN ROUND(SUM(campaign.pledged)*1.43)
WHEN currency.name='NOK' THEN ROUND(SUM(campaign.pledged)*9.28)
WHEN currency.name='EUR' THEN ROUND(SUM(campaign.pledged)*0.87)
WHEN currency.name='MXN' THEN ROUND(SUM(campaign.pledged)*22.48)
WHEN currency.name='SEK' THEN ROUND(SUM(campaign.pledged)*0.04)
WHEN currency.name='NZD' THEN ROUND(SUM(campaign.pledged)*1.53)
WHEN currency.name='CHF' THEN ROUND(SUM(campaign.pledged)*0.94)
WHEN currency.name='DKK' THEN ROUND(SUM(campaign.pledged)*6.52)
WHEN currency.name='HKD' THEN ROUND(SUM(campaign.pledged)*7.75)
WHEN currency.name='SGD' THEN ROUND(SUM(campaign.pledged)*1.39)
WHEN currency.name='JPY' THEN ROUND(SUM(campaign.pledged)*107.11)
ELSE ROUND(SUM(campaign.pledged),2)
END AS 'Amount Raised'
FROM campaign
LEFT JOIN currency ON currency.id=campaign.currency_id
GROUP BY `Campaign Length`,currency.id;
但结果并没有按照我的意图进行分组:
Campaign Length. ---- Amount Raised
Short Campaign. ---- XXXXXXXXXXXXX
Mid-Lengthed Campaign ---- XXXXXXXXXXXXX
Long Campaign. ---- XXXXXXXXXXXXX
Mid-Lengthed Campaign ---- XXXXXXXXXXXXX
Mid-Lengthed Campaign ---- XXXXXXXXXXXXX
Short Campaign. ---- XXXXXXXXXXXXX
我尝试了很多方法,但找不到解决方案
您需要在聚合 function 中移动货币名称上的case
表达式:
SELECT
CASE
WHEN DATEDIFF(ca.deadline,ca.launched) <= 30 THEN
'Short Campaign'
WHEN DATEDIFF(ca.deadline,ca.launched) <= 60
THEN 'Mid-lengthed Campaign'
ELSE 'Long Campaign'
END AS campaign_length,
ROUND(SUM(
ca.pledged
* CASE cu.name
WHEN 'GBP' THEN 0.8
WHEN 'CAD' THEN 1.36
WHEN 'AUD' THEN 1.43
...
ELSE 1
END
), 2) as amount_raised
FROM campaign ca
LEFT JOIN currency cu ON cu.id = ca.currency_id
GROUP BY campaign_length;
其他需要注意的事项:
不要对列标识符使用单引号 - 它们用于文字字符串(MySQL 需要反引号); 事实上,使用不需要引用的标识符更简单
两种case
表达式都可以简化,如上所示; 在第一个中,不需要检查第二个分支中的活动持续时间是否大于 30(第一个分支已经陷阱); 在第二个中,您可以使用短路形式而不是在每个分支中重复列名
表别名使查询更易于编写和阅读
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.