不按问题分组

  • 本文关键字:问题 sql oracle
  • 更新时间 :
  • 英文 :


我试图在这个公式中求和,但我有一个问题,不是按表达式分组?

问题出在哪里?

SELECT ROUND( SUM( FACT_WLT_AGENT.WLT_LHV_PO_FNGF + 
FACT_WLT_AGENT.WLT_LHV_PO_ENA +
FACT_WLT_AGENT.WLT_LHV_PO_EEIND +
FACT_WLT_AGENT.WLT_LHV_PO_PAQ
) /
3600 * 10
)
FROM FACT_WLT_AGENT,
dim_reorganization reorg
WHERE FACT_WLT_AGENT.reorg_id = reorg.reorg_id
AND is_last_master_reorg    = 'Y'
HAVING FACT_WLT_AGENT.WLT_LHV_PO_FNGF +
FACT_WLT_AGENT.WLT_LHV_PO_ENA + 
FACT_WLT_AGENT.WLT_LHV_PO_EEIND +
FACT_WLT_AGENT.WLT_LHV_PO_PAQ /
3600 > 0

为了说明这个问题,我将使用修改后的Scott的示例模式。

SQL> select sal, comm from emp where deptno = 10;
SAL       COMM
---------- ----------
2450        245
5000        500
1300        130
SQL>

这是您当前的代码(不起作用(:

SQL> select sum(sal + comm) result
2  from emp
3  where deptno = 10
4  having sal + comm > 0;
having sal + comm > 0
*
ERROR at line 4:
ORA-00979: not a GROUP BY expression

SQL>

现在,您可以"修复";通过添加group by子句,但我不认为这是您想要的:

SQL> select sum(sal + comm) result
2  from emp
3  where deptno = 10
4  group by sal + comm
5  having sal + comm > 0;
RESULT
----------
5500
2695
1430
SQL>

我相信您实际上想要在having子句中使用这种聚合:

SQL> select sum(sal + comm) result
2  from emp
3  where deptno = 10
4  having sum(sal + comm) > 0;
RESULT
----------
9625
SQL>

或者,在您的情况下:

SELECT ROUND( SUM( FACT_WLT_AGENT.WLT_LHV_PO_FNGF + 
FACT_WLT_AGENT.WLT_LHV_PO_ENA +
FACT_WLT_AGENT.WLT_LHV_PO_EEIND +
FACT_WLT_AGENT.WLT_LHV_PO_PAQ
) /
3600 * 10
)
FROM FACT_WLT_AGENT,
dim_reorganization reorg
WHERE FACT_WLT_AGENT.reorg_id = reorg.reorg_id
AND is_last_master_reorg    = 'Y'
HAVING sum(FACT_WLT_AGENT.WLT_LHV_PO_FNGF +
FACT_WLT_AGENT.WLT_LHV_PO_ENA + 
FACT_WLT_AGENT.WLT_LHV_PO_EEIND +
FACT_WLT_AGENT.WLT_LHV_PO_PAQ) > 0;

group by是在sumhaving中命名的任何字段的必需项。在这种情况下,你两者都有,所以你需要这样的东西;

SELECT ROUND(SUM(FACT_WLT_AGENT.WLT_LHV_PO_FNGF + FACT_WLT_AGENT.WLT_LHV_PO_ENA + FACT_WLT_AGENT.WLT_LHV_PO_EEIND + FACT_WLT_AGENT.WLT_LHV_PO_PAQ)/ 3600 * 10 )
FROM FACT_WLT_AGENT, dim_reorganization reorg 
WHERE FACT_WLT_AGENT.reorg_id = reorg.reorg_id 
AND is_last_master_reorg = 'Y' 
group by FACT_WLT_AGENT.WLT_LHV_PO_FNGF, FACT_WLT_AGENT.WLT_LHV_PO_ENA, FACT_WLT_AGENT.WLT_LHV_PO_EEIND, FACT_WLT_AGENT.WLT_LHV_PO_PAQ
HAVING FACT_WLT_AGENT.WLT_LHV_PO_FNGF + FACT_WLT_AGENT.WLT_LHV_PO_ENA + FACT_WLT_AGENT.WLT_LHV_PO_EEIND + FACT_WLT_AGENT.WLT_LHV_PO_PAQ / 3600 > 0

select语句在[概念上]是这样按顺序评估的,尽管应该注意到,出于性能原因,在内部,事情不太可能真正以这种方式工作:

  • 形成from子句中所有表的笛卡尔乘积
  • 应用联接条件(如果有(,删除任何不匹配的行
  • 应用where子句中的条件(如果有(,再次删除任何不匹配的行
  • 如果存在CCD_ 9子句,
    • 将每组折叠/汇总为一行,计算所有聚合函数的值,并删除不在group by列表中或是聚合函数的所有列/表达式
    • 应用having子句中的条件(如果有(来筛选结果集
  1. 对由order by子句中指定的列/表达式设置的结果进行排序

如果没有首先指定group by子句,则无法指定having子句。缺少group by子句,您的having子句在语法上无效。

我只需使用派生表,既可以节省一些类型,也可以减少重复相同列时出错的风险:

SELECT the_sum
FROM
(
SELECT ROUND( SUM( FACT_WLT_AGENT.WLT_LHV_PO_FNGF + 
FACT_WLT_AGENT.WLT_LHV_PO_ENA +
FACT_WLT_AGENT.WLT_LHV_PO_EEIND +
FACT_WLT_AGENT.WLT_LHV_PO_PAQ
) / 3600 * 10) as the_sum
FROM FACT_WLT_AGENT
JOIN dim_reorganization reorg
ON FACT_WLT_AGENT.reorg_id = reorg.reorg_id
WHERE is_last_master_reorg    = 'Y
) dt
WHERE the_sum > 0;

注意明确的JOIN语法!更易于编写(没有错误(,更易于阅读和维护,如果需要,更易于转换为外部联接!

相关内容

  • 没有找到相关文章

最新更新