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

时间:2013-06-05 17:44:31

标签: oracle function plsql group-by subquery

我有一个类似于下面的查询(虽然更复杂)。在运行它时,我收到以下错误:{group =}在我的group by语句中。

解决此问题的最佳方法是什么?

ORA-22818: Subquery expressions not allowed here

2 个答案:

答案 0 :(得分:1)

您的代码示例看起来像是在使用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

答案 1 :(得分: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标准,更灵活,并且具有短路评估功能,因此您的代码库很方便,有很多PL / SQL函数可以获得在SQL中调用。