为什么MySQL查询没有在Oracle 11g中编译?

时间:2013-03-12 19:43:13

标签: sql oracle oracle11g

您好,我在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

你知道这段代码有什么问题吗?

3 个答案:

答案 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。请确保它仍能产生您期望的结果。