0

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

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

4

3 回答 3

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

于 2013-03-12T20:04:16.520 回答
1

除了格兰特的回答,还有其他一些优化。

您可能想替换:

 CASE WHEN c.name IS NULL THEN '- Unknow -' ELSE c.name END

和:

 Coalesce(c.name,'- Unknow -')

此外,您正在多个级别进行聚合,并且有一种语法会更有效且更少冗长:GROUP BY ROLLUP()

Tim Hall 有一篇关于高级分组主题的非常好的文章:http ://www.oracle-base.com/articles/misc/rollup-cube-grouping-functions-and-grouping-sets.php

如果您决定不使用 ROLLUP 则将 UNION 更改为 UNION ALL - UNION 有一个隐含的 distinct 在这里什么都不做。

于 2013-03-12T20:11:33.127 回答
1

这是运行的更新SQL Fiddle。请确保它仍然产生您期望的结果。

于 2013-03-12T20:12:58.817 回答