简体   繁体   中英

Oracle SQL Correlated subquery - Returning count(*) in some columns

I have my initial statement which is :

  SELECT TEAM.ID PKEY_SRC_OBJECT,
  TEAM.MODF_DAT UPDATE_DATE,
  TEAM.MODF_USR UPDATED_BY,
  PERSO.FIRST_NAM FISRT_NAME
  FROM TEAM
  LEFT OUTER JOIN PERSO ON (TEAM.ID=PERSO.TEAM_ID)

I want to calculate some "flags" and return them in my initial statement. There are 3 flags which can be calculated like this :

1) Flag ISMASTER:

SELECT Count(*)
FROM TEAM_TEAM_REL A, TEAM B
WHERE B.PARTY_PTY_ID = A.RLTD_TEAM_ID
AND CODE = 'Double';

2) Flag ISAGENT:

SELECT Count(*) 
FROM TEAM_ROL_REL A, TEAM B
WHERE B.PARTY_PTY_ID = A.TEAM_ID;

3) Flag NUMPACTS:

SELECT Count(*) 
FROM TEAM_ROL_REL A,
TEAM_ROL_POL_REL B, 
PERSO_POL_STA_REL C,
TEAM D
WHERE A.ROL_CD IN ('1','2') 
AND A.T_ROL_REL_ID = B.P_ROL_REL_ID
AND B.P_POL_ID = C.P_POL_ID
AND C.STA_CD = 'A'
AND D.PARTY_PTY_ID = A.TEAM_ID;

To try to achieve this, I've updated my initial statement like this :

WITH ABC AS (
  SELECT TEAM.ID PKEY_SRC_OBJECT,
  TEAM.MODF_DAT UPDATE_DATE,
  TEAM.MODF_USR UPDATED_BY,
  PERSO.FIRST_NAM FISRT_NAME
  FROM TEAM
  LEFT OUTER JOIN PERSO ON (TEAM.ID=PERSO.TEAM_ID)
)

SELECT ABC.*, MAST.ISMASTER, AGENT.ISAGENT, PACTS.NUMPACTS FROM ABC
LEFT OUTER JOIN (
  select
  RLTD_TEAM_ID,
  Count(RLTD_TEAM_ID) OVER (PARTITION BY RLTD_TEAM_ID) as ISMASTER
  FROM TEAM_TEAM_REL
  WHERE CODE = 'Double'
) MAST
ON ABC.PKEY_SRC_OBJECT = MAST.RLTD_TEAM_ID

LEFT OUTER JOIN (
  select
  TEAM_ID,
  Count(TEAM_ID) OVER (PARTITION BY TEAM_ID) as ISAGENT
  FROM TEAM_ROL_REL
) AGENT
ON ABC.PKEY_SRC_OBJECT = AGENT.TEAM_ID

LEFT OUTER JOIN (
  select
  TEAM_ID,
  Count(TEAM_ID) OVER (PARTITION BY TEAM_ID) as NUMPACTS
  FROM TEAM_ROL_REL, TEAM_ROL_POL_REL, PERSO_POL_STA_REL
  WHERE TEAM_ROL_REL.ROL_CD IN ('1','2') 
  AND TEAM_ROL_REL.T_ROL_REL_ID = TEAM_ROL_POL_REL.P_ROL_REL_ID
  AND TEAM_ROL_POL_REL.P_POL_ID = PERSO_POL_STA_REL.P_POL_ID
  AND PERSO_POL_STA_REL.STA_CD = 'A'
) PACTS
ON ABC.PKEY_SRC_OBJECT = PACTS.TEAM_ID;

For the two first flags (ISMASTER and ISAGENT) I get the result in less than 1min, but for the last flag (NUMPACTS) it runs few minutes without provide any result. I think my statement is too heavy, maybe I should do it in a totally different way.

I think you have perhaps over complicated things.

You could do this (assuming I have understood your requirements correctly) like so:

WITH   ttr AS (SELECT rltd_team_id,
                      COUNT(*) is_master
               FROM   team_team_rel
               AND    CODE = 'Double'
               GROUP BY rltd_team_id),
       trr AS (SELECT team_id,
                      COUNT(*) is_agent
               FROM   team_rol_rel
               GROUP BY team_id)
     pacts AS (SELECT trr1.team_id,
                      COUNT(*) num_pacts
               FROM   team_rol_rel trr1
                      INNER JOIN team_rol_pol_rel trpr ON (trr1.t_rol_rel_id = trpr.p_rol_rel_id)
                      INNER JOIN perso_pol_sta_rel ppsr ON (trpr.p_pol_id = ppsr.p_pol_id
               WHERE  trr1.rol_cd IN ('1', '2')
               AND    ppsr.st_cd = 'A'
               GROUP BY trr1.team_id)
SELECT t.id pkey_src_object,
       t.modf_dat update_date,
       t.modf_usr updated_by,
       p.first_nam first_name,
       ttr.is_master,
       trr.is_agent,
       pacts.num_pacts
FROM   team t
       LEFT OUTER JOIN perso p ON t.id = p.team_id
       LEFT OUTER JOIN ttr ON t.party_pty_id = ttr.rltd_team_id
       LEFT OUTER JOIN trr ON t.party_pty_id = trr.team_id
       LEFT OUTER JOIN pacts ON t.pkey_src_object = pacts.team_id;

NB untested, since you didn't provide any test data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM