是否可以在一个查询中引用多个listagg语句引用多个表?

时间:2015-08-10 17:23:24

标签: oracle listagg

我有三个LISTAGG语句如下:

LISTAGG (ga.FULL_APPL_NUM, ',') WITHIN GROUP (ORDER BY   ga.FULL_APPL_NUM) AS "FullApplNums",
LISTAGG (ga.APPL_ID, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "ApplIds",
LISTAGG (ga.PROJECT_TITLE, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "ProjectTitles",

结果如下:

FullApplNums
2r01HL02858573-23A1,5R01HL02857324,...
ApplIds
7219924,6718409,...
ProjectTitles
ProjectTitle1,ProjectTitle2,...

这些列都将同一记录从连接中的一个表引用到大约4个表,但它们都来自同一个表 - ga。

我需要另一个列表来填充一个列,但它来自另一个别名为pp的表。 是否有可能LISTAGG再次引用另一个表以及如何同步这些值,因为逗号动画列表像索引数组一样使用。 所以我可以从ga [“FULL_APPL_NUM”] [0],ga [“APPL_ID”] [1],ga [“PROJECT_TITLE”] [0]建立记录。

现在我需要ga [“IsContact”] [0],但它会来自pp table not ga。

或者是否可以执行子选择查询,如: SELECT * FROM pp其中appl_id in(ApplIds) - 其中ApplIds是列表agg的结果。

到目前为止,这是整个查询:

 PROCEDURE GetPrincipalInvestigators
      (
 loginId          IN VARCHAR2 := NULL,
 portfolioId      IN NUMBER := NULL,
 portfolioType    IN VARCHAR := NULL,
 ic               IN VARCHAR2 := NULL,
 startRow         IN INT := NULL,
 endRow           IN INT := NULL,
 sortField        IN VARCHAR2 := NULL,
 sortDirection    IN VARCHAR2 := NULL,
 PrincipalInvestigators_CUR IN OUT SYS_REFCURSOR
  )
      IS
          v_APPL_ID               NUMBER(10,0) := 0;  
  v_ADMIN_PHS_ORG_CODE    VARCHAR2(2 BYTE) := '  ';
  v_SERIAL_NUM            NUMBER(6,0) := 0;
  v_Proj_Appl_Rec         Proj_Appl_Rec;        
  v_Proj_Appl_Tab         Proj_Appl_Tab := Proj_Appl_Tab(); 
  v_Proj_Appl_Cur         SYS_REFCURSOR;
  v_sortField             VARCHAR2(50 BYTE) := NULL;
  v_sortDirection         VARCHAR2(4 BYTE)  := NULL;
  v_cnt                   NUMBER := 0;
  v_orderBy               VARCHAR2(200 BYTE) := ' ORDER BY ';
  v_sql                   CLOB := ' ';  

  BEGIN  
      IF sortField IS NULL THEN
        v_sortField := 'LAST_NAME';
      ELSE
        v_sortField := sortField;
      END IF;

      IF sortDirection IS NULL THEN
        v_sortDirection := 'DESC';
      ELSE
        v_sortDirection := sortDirection;
      END IF;

      v_orderBy := v_orderBy || v_sortField || ' ' || v_sortDirection; 
      --DBMS_OUTPUT.PUT_LINE(v_orderBy); 

      IREPORT_PORTFOLIOS.GetPortfolioAppsAndProjects
      (
        loginId => loginId,
        portfolioId => portfolioId,
        portfolioType => portfolioType,
        ic => ic,
        AppIds_CUR => v_Proj_Appl_Cur
      );

      LOOP
          FETCH v_Proj_Appl_Cur         
          INTO v_APPL_ID, v_ADMIN_PHS_ORG_CODE, v_SERIAL_NUM;        
          EXIT WHEN v_Proj_Appl_Cur%NOTFOUND;        
          v_Proj_Appl_Tab.extend;
          v_cnt := v_cnt + 1;
          v_Proj_Appl_Tab(v_cnt) := Proj_Appl_Rec(v_APPL_ID, v_ADMIN_PHS_ORG_CODE, v_SERIAL_NUM);        
      END LOOP;
      CLOSE v_Proj_Appl_Cur; 

      OPEN PrincipalInvestigators_CUR FOR
          WITH projects_CTE
          AS 
          (
             SELECT DISTINCT
                    pa.APPL_ID,
                    pa.ADMIN_PHS_ORG_CODE,
                    pa.SERIAL_NUM
               FROM TABLE(v_proj_appl_tab) pa
          )

          SELECT
                pp.PERSON_PROFILE_ID AS PersonProfileId,
                pp.LAST_NAME, FIRST_NAME,
                (pp.LAST_NAME || ' , ' || pp.FIRST_NAME) AS InvestigatorName,
                pp.ORG_NAME AS PrimaryEmployer,
                pp.EMAIL_ADDR AS Email,
                pp.PHONE_NUM AS Phone,
                COUNT(*),
                LISTAGG (ga.FULL_APPL_NUM, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "FullApplNums",
                LISTAGG (ga.APPL_ID, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "ApplIds",
                LISTAGG (ga.PROJECT_TITLE, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "ProjectTitles"
          FROM projects_CTE pcte
          JOIN APPL_PIS apis
          ON pcte.APPL_ID = apis.APPL_ID
          JOIN PERSON_PROFILES pp
          ON pp.PERSON_PROFILE_ID = apis.CONTACT_PI_PROFILE_PERSON_ID
          JOIN GRANT_APPLS ga
          ON ga.APPL_ID = pcte.APPL_ID
          WHERE 
          ga.APPL_TYPE_CODE <> 3  -- Non Supplement
          AND rownum < 100
          GROUP BY PERSON_PROFILE_ID, LAST_NAME, FIRST_NAME, ORG_NAME, EMAIL_ADDR,PHONE_NUM  ;

  END GetPrincipalInvestigators;

对不起,这很难解释。 也许有人会有比这更好的方法。

1 个答案:

答案 0 :(得分:1)

假设每个par(xaxs='i',yaxs='i'); xlim <- c(0,length(levels(df$pace))); ylim <- c(0,(max(df$outside)+5)%/%5*5); plot(as.integer(df$pace)-0.5,df$outside,xlim=xlim,ylim=ylim,pch=4,col=c('darkred','darkgreen','darkblue','darkcyan','darkmagenta')[df$pace],axes=F,xlab='Pace of Lecture',ylab='Hours Outside of Lecture'); axis(1,c(0,length(levels(df$pace))),NA,tck=0); axis(1,seq_along(levels(df$pace))-0.5,levels(df$pace),lwd=0,lwd.ticks=1); axis(2); 结果只有一个pp匹配 - 也就是每个组一个 - 并且它不为空,您可以在按另一个表排序时聚合一个表中的列:

ga

与其他聚合相同的LISTAGG (pp.IS_CONTACT, ',') WITHIN GROUP (ORDER BY ga.FULL_APPL_NUM) AS "IsContact" 列进行排序意味着它们的条目将按照适当的顺序排列 - 因此它们将保持同步。但是如果一个ga(或者它真正被称为的任何东西)为null,那么就不会包含它,这会丢掉你的索引。