Adding filters in subquery from CTE quadruples run time

时间:2019-04-23 15:14:40

标签: oracle reporting-services subquery

I am working on an existing query for SSRS report that focuses on aggregated financial aid data split out into 10 aggregations. User wants to be able to select students included in that aggregated data based on new vs. returning and 'selected for verification.' For the new/returning status, I added a CTE to return the earliest admit date for a student. 2 of the 10 data fields are created by a subquery. I have been trying for 3 days to get the subquery to use the CTE fields for a filter, but they won't work. Either they're ignored or I get a 'not a group by expression' error. If I put the join to the CTE within the subquery, the query time jumps from 45 second to 400 seconds. This shouldn't be that complicated! What am I missing? I have added some of the code... 3 of the chunks work - paid_something doesn't.

with stuStatus as
(select 
person_uid, min(year_admitted) admit_year
from academic_study
where aid_year between :AidYearStartParameter and :AidYearEndParameter 
group by person_uid)
--- above code added to get student information not originally in qry

select
  finaid_applicant_status.aid_year   
  , count(1) as fafsa_cnt           --works
  , sum(                           --works
    case 
      when (
        package_complete_date is not null
       and admit.status      is not null
     ) 
    then 1
  else 0
end
  ) as admit_and_package


 , (select count(*)               --does't work
from (
select distinct award_by_aid_year.person_uid
      from 
       award_by_aid_year
     where 
       award_by_aid_year.aid_year = finaid_applicant_status.aid_year
       and award_by_aid_year.total_paid_amount > 0  )dta
 where 
   (
    (:StudentStatusParameter = 'N' and stuStatus.admit_year = finaid_applicant_status.aid_year)
    OR 
    (:StudentStatusParameter = 'R' and stuStatus.admit_year <> finaid_applicant_status.aid_year)
    OR :StudentStatusParameter = '%'
       )
  ) 
  as paid_something

  , sum(                           --works
    case 
     when exists (
       select 
         1 
    from 
      award_by_person  abp
    where 
      abp.person_uid            = fafsa.person_uid
      and abp.aid_year          = fafsa.aid_year
      and abp.award_paid_amount > 0
  ) and fafsa.requirement is not null
    then 1
  else 0
end
 ) as paid_something_fafsa

from
 finaid_applicant_status
 join finaid_tracking_requirement fafsa
on finaid_applicant_status.person_uid = fafsa.person_uid
and finaid_applicant_status.aid_year  = fafsa.aid_year
and fafsa.requirement                 = 'FAFSA'
  left join finaid_tracking_requirement admit
on finaid_applicant_status.person_uid  = admit.person_uid
and finaid_applicant_status.aid_year   = admit.aid_year
and admit.requirement                  = 'ADMIT'
and admit.status                      in ('M', 'P')
  left outer join stuStatus
on finaid_applicant_status.person_uid = stuStatus.person_uid

where
  finaid_applicant_status.aid_year between :AidYearStartParameter and :AidYearEndParameter 
 and (
   (:VerifiedParameter = '%') OR
   (:VerifiedParameter <> '%' AND finaid_applicant_status.verification_required_ind = :VerifiedParameter)
     )
    and 
           (
            (:StudentStatusParameter = 'N' and (stuStatus.admit_year IS NULL OR stuStatus.admit_year = finaid_applicant_status.aid_year ))
           OR 
           (:StudentStatusParameter = 'R' and stuStatus.admit_year <> finaid_applicant_status.aid_year)
           OR :StudentStatusParameter = '%'
             )
group by
  finaid_applicant_status.aid_year
order by
  finaid_applicant_status.aid_year

1 个答案:

答案 0 :(得分:0)

不确定这是否有帮助,但是您有类似以下内容:

select aid_year, count(1) c1,
      (select count(1) 
         from (select distinct person_uid 
                 from award_by_aid_year a 
                 where a.aid_year = fas.aid_year))
  from finaid_applicant_status fas
  group by aid_year;

此查询引发ORA-00904 FAS.AID_YEAR invalid identifier。这是因为fas.aid_year在子查询中嵌套太深。

如果您能够将子查询从select count(1) from (select distinct sth from ... where year = fas.year)修改为select count(distinct sth) from ... where year = fas.year,那么它就有机会工作。

select aid_year, count(1) c1,
       (select count(distinct person_uid) 
          from award_by_aid_year a 
          where a.aid_year = fas.aid_year) c2
  from finaid_applicant_status fas
  group by aid_year

此处简化了demo,其中显示了无效查询和有效查询。当然,您的查询要复杂得多,但是您可以检查一下。

也许您也可以使用dbfiddle或sqlfiddle来设置一些测试用例?还是向我们展示样本(匿名)数据和所需的输出?