您好,我在Oracle 11g下调用SQL查询时遇到问题。在MySQL下工作正常。
请看SQLFIDDLE:
(SELECT IF(c.name IS NULL, '- Unknow -', c.name) as name,
v.site,
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
0 'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name, v.site)
union(
SELECT IF(c.name IS NULL, '- Unknow -', c.name) as name,
'- All -',
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
1 'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name)
UNION (
SELECT '- All -',
'- All -',
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
1 'isAll'
FROM violations v LEFT JOIN country c ON c.name = v.country)
ORDER BY name, isAll DESC, site
你知道这段代码有什么问题吗?
答案 0 :(得分:2)
有一些问题......
首先,IF()
在Oracle中不是有效的语法。您需要将其更改为CASE
语句。
其次,您不能使用''命名列。所以你需要去掉''来自'isAll'。
最后,您按网站排序,但实际上并未对该列进行命名。
最终查询应如下所示:
(SELECT CASE WHEN c.name IS NULL THEN '- Unknow -' ELSE c.name END as name,
v.site as site,
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
0 isAll
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name, v.site)
UNION (
SELECT CASE WHEN c.name IS NULL THEN '- Unknow -' ELSE c.name END as name,
'- All -' as site,
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
1 isAll
FROM violations v LEFT JOIN country c ON c.name = v.country
GROUP BY c.name )
UNION (
SELECT '- All -',
'- All -' as site,
SUM(CASE WHEN v.status_id = 1 THEN 1 ELSE 0 END) Total_SuspectedViolations,
SUM(CASE WHEN v.status_id = 2 THEN 1 ELSE 0 END) Total_ConfirmedViolations,
SUM(CASE WHEN v.status_id = 3 THEN 1 ELSE 0 END) Total_ConfirmedNoViolations,
SUM(CASE WHEN v.status_id = 4 THEN 1 ELSE 0 END) Total_NotDetermined,
COUNT(*) Total,
1 isAll
FROM violations v LEFT JOIN country c ON c.name = v.country)
ORDER BY name, isAll DESC, site
您可以在此SQLFiddle中进行测试:http://sqlfiddle.com/#!4/93c94/55
答案 1 :(得分:1)
继格兰特的回答之后,还有其他一些优化措施。
您可能想要替换:
CASE WHEN c.name IS NULL THEN '- Unknow -' ELSE c.name END
使用:
Coalesce(c.name,'- Unknow -')
此外,您正在多个级别进行聚合,并且有一种语法可以提高效率,减少冗长:GROUP BY ROLLUP()
蒂姆·霍尔在这里对高级分组主题进行了非常好的撰写:http://www.oracle-base.com/articles/misc/rollup-cube-grouping-functions-and-grouping-sets.php
如果你决定不使用ROLLUP,那么将UNION更改为UNION ALL - UNION有一个隐含的不同,在这里什么都不做。
答案 2 :(得分:1)
以下是您运行的更新SQL Fiddle。请确保它仍能产生您期望的结果。