分组依据中的子查询(ORACLE 9i)

分组依据中的子查询(ORACLE 9i),oracle,function,plsql,group-by,subquery,Oracle,Function,Plsql,Group By,Subquery,我有一个类似于下面的查询(尽管更复杂)。运行它时,我得到以下错误:ORA-22818:在我的GROUPBY语句中,此处不允许使用子查询表达式 对我来说,回避这个问题的最佳方式是什么 SELECT table1.ID NVL(fget_office(fget_last_catc_id_by_date((SELECT MAX(table3.date) FROM table3 INNER JOIN table1 ON table1.ID = table3.id),table1.NU

我有一个类似于下面的查询(尽管更复杂)。运行它时,我得到以下错误:
ORA-22818:在我的GROUPBY语句中,此处不允许使用子查询表达式

对我来说,回避这个问题的最佳方式是什么

SELECT table1.ID   
       NVL(fget_office(fget_last_catc_id_by_date((SELECT MAX(table3.date) FROM table3 INNER JOIN table1 ON table1.ID = table3.id),table1.NUM), fget_max_split_line_no('FILL',(SELECT MAX table3.tc_id) FROM table3 INNER JOIN table1 ON table1.ID = table3.ID INNER JOIN table4 ON table3.tc_id = table3.tc_id))), table1.distribution) "OFFICE", --eper.DISTRIBUTION "OFFICE",
       table1.name 
  FROM table1
  LEFT JOIN table2
    ON table1.ID = table2.ID 
 WHERE table1.company in ('CP01', 'CP02')
 GROUP BY table1.ID,
          NVL(fget_office(fget_last_catc_id_by_date((SELECT MAX(table3.date) FROM table3 INNER JOIN table1 ON table1.ID = table3.id),table1.NUM), fget_max_split_line_no('FILL',(SELECT MAX table3.tc_id) FROM table3 INNER JOIN table1 ON table1.ID = table3.ID INNER JOIN table4 ON table3.tc_id = table3.tc_id))), table1.distribution),          
          table1.name

您的代码示例看起来像是在使用
groupby
来提取不同的行。在这种情况下,请尝试以下方法:

SELECT DISTINCT
       table1.ID   
       NVL(fget_office(fget_last_catc_id_by_date((SELECT MAX(table3.date) FROM table3 INNER JOIN table1 ON table1.ID = table3.id),table1.NUM), fget_max_split_line_no('FILL',(SELECT MAX table3.tc_id) FROM table3 INNER JOIN table1 ON table1.ID = table3.ID INNER JOIN table4 ON table3.tc_id = table3.tc_id))), table1.distribution) "OFFICE", --eper.DISTRIBUTION "OFFICE",
       table1.name 
  FROM table1
  LEFT JOIN table2
    ON table1.ID = table2.ID 
 WHERE table1.company in ('CP01', 'CP02')
如果您真的在“real”查询中进行聚合,一个快速的解决方法是使用公共表表达式(CTE),这在Oracle 9i中是受支持的。本例假设您对名为
某个\u值的列求和

WITH x AS (
  SELECT table1.ID   
         NVL(fget_office(fget_last_catc_id_by_date((SELECT MAX(table3.date) FROM table3 INNER JOIN table1 ON table1.ID = table3.id),table1.NUM), fget_max_split_line_no('FILL',(SELECT MAX table3.tc_id) FROM table3 INNER JOIN table1 ON table1.ID = table3.ID INNER JOIN table4 ON table3.tc_id = table3.tc_id))), table1.distribution) "OFFICE", --eper.DISTRIBUTION "OFFICE",
         table1.name,
         some_value
    FROM table1
    LEFT JOIN table2
      ON table1.ID = table2.ID 
   WHERE table1.company in ('CP01', 'CP02')
)
SELECT ID, OFFICE, name, SUM(some_value)
FROM x
GROUP BY ID, Office, name

在我看来,这些函数的结果是由表1的值直接或间接决定的

如果是这样,您可以对表1和表2中的一组简单数据执行distinct操作,然后应用这些函数。这将减少对函数的调用次数并提高效率

with cte1 as (
  select
    table1.id   
    table1.num
    table1.distribution,
    table1.name 
  from
    table1 left join table2 on (table1.id = table2.id)
 where
   table1.company in ('CP01', 'CP02'))
select
  cte1.id,
  coalesce(
    fget_office(
      fget_last_catc_id_by_date(
        (select max(table3.date)
         from   table3 inner join cte1 on cte1.id = table3.id),
        cte1.num),
      fget_max_split_line_no(
        'FILL',
        (select max(table3.tc_id)
         from   table3 inner join cte1   on cte1.id      = table3.id
                       inner join table4 on table3.tc_id = table3.tc_id))),
    table1.distribution) office
  cte1.name 
from cte1
/
您还可以习惯使用Coalesce()而不是Nvl()——它符合ANSI标准,更灵活,并且具有短路求值功能,因此您的代码库有很多在SQL中调用的PL/SQL函数,这非常方便