1

I have a query that looks similar to the one below (albeit more complicated). When running it I get the following error: ORA-22818: Subquery expressions not allowed here in my group by statement.

What is the best way for me to get around this issue?

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
4

2 回答 2

2

您的代码示例看起来GROUP BY只是用来提取不同的行。在这种情况下,试试这个:

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')

如果您真的在“真实”查询中进行聚合,一个快速的解决方法是使用 Oracle 9i 支持的公用表表达式 (CTE)。此示例假设您正在对名为 的列求和some_value

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
于 2013-06-05T17:51:59.807 回答
1

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

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

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 函数.

于 2013-06-05T18:42:47.930 回答