Dynamic query in PIVOT IN clause - oracle

I need to write a dynamic query inside In clause of pivot query in oracle 11g. With Pivot xml, it is possible, but I do not need the xml one. Here is the code snippet.
WITH pivot_data AS (
select cu.id, u.topic, cu.first_name, cu.last_name, cu.email,
trunc(cu.REGISTRATION_DATE) Register_Date,
trunc(min(u.view_date)) First_Visit,
trunc(max(u.view_date)) Last_Visit,
nvl(sum(u.user_visits),0) Visits,
nvl(sum(u.time_in_topic),0) Time_in_Topic,
ffl.label label, ffv.field_value val
from ACTIVE_USER_VIEWS_BY_TOPIC u
LEFT join cl_user cu
on u.user_id=cu.id
LEFT JOIN CL_PROFILE_FIELD_LABEL ffl
on ffl.cl_customer_accounts_id=cu.cl_customer_accounts_id
LEFT JOIN CL_PROFILE_FIELD_VALUE ffv
on ffl.id = ffv.profile_field_label_id and ffv.user_id= cu.id
LEFT JOIN CL_PROFILE_FIELD_ASSIGNMENT ffa
on ffl.id = ffa.profile_field_label_id
where ffl.cl_customer_accounts_id = (
select cl_customer_accounts_id
from CL_USER where ID = cu.id)
and ffl.ENABLED = 'Y'
and u.PURCHASED_PRODUCT_ID = 582002861
and REGEXP_LIKE (u.topic,
'difficult_interactions|customer_focus|leading_people' )
group by cu.id, u.topic, cu.first_name, cu.last_name, cu.email,
cu.REGISTRATION_DATE, trunc(u.view_date,'MONTH'), ffl.label,
ffv.field_value
)
SELECT *
FROM pivot_data
PIVOT (
max(val)
FOR label
IN ('Flexfield1' AS Flexfield1, 'Flexfield2' AS Flexfield2,
'Flexfield3' AS Flexfield3, 'Flexfield4' AS Flexfield4,
'Flexfield5' AS Flexfield5, 'Flexfield6' AS Flexfield6,
'flexfield021' AS flexfield021, 'sdcs' AS sdcs)
)
I have the query for dynamic data creation i.e.
SELECT DISTINCT
LISTAGG('''' || label || ''' AS ' || label,',')
WITHIN GROUP (ORDER BY label) AS temp_in_statement
FROM (
select distinct label
from cl_profile_field_label
where cl_customer_accounts_id=(
select cl_customer_accounts_id
from cl_purchased_product
where id=582002861));
But if I put the dynamic query inside pivot IN clause, I am getting the error as ORA-00936: missing expression. Please help me out.

Related

running balance debit credit column in oracle query

Output result
I want the running balance in my query. I had wrote the query.
May be i am mistaking any where please let me know.
SELECT
ACC_VMAST.VM_DATE,
ACC_VDET.CHEQUE,
ACC_VMAST.NARRATION,
ACC_VDET.DEBIT,
ACC_VDET.CREDIT,
sum(nvl(ACC_VDET.DEBIT,0) - nvl(ACC_VDET.CREDIT,0) )
over (order by ACC_VMAST.VM_DATE , ACC_VDET.DEBIT ) running_bal
FROM ACC_VMAST,
ACC_VDET,
ACC_COA
WHERE ACC_VMAST.VM_PK=ACC_VDET.VM_PK
AND ACC_COA.COA_PK=ACC_VDET.COA_PK
AND ACC_VMAST.POST_BY IS NOT NULL
AND ACC_VMAST.CANCEL_STATUS IS NULL
AND ACC_VMAST.VM_DATE BETWEEN '07/06/2021' AND '07/07/2021'
AND ACC_VDET.COA_PK= '303'
ORDER BY ACC_VMAST.VM_DATE , ACC_VDET.DEBIT;
If you have rows that have the same values for the ORDER BY clause then when you SUM the values then all the rows with the same ORDER BY value will be grouped together and totalled.
To prevent that, you can add the ROWNUM pseudo-column to the ORDER BY clause of the analytic function so that there will not be any ties:
SELECT m.VM_DATE,
d.CHEQUE,
m.NARRATION,
d.DEBIT,
d.CREDIT,
SUM( COALESCE(d.DEBIT,0) - COALESCE(d.CREDIT,0) )
OVER ( ORDER BY m.VM_DATE, d.DEBIT, ROWNUM ) AS running_bal
FROM ACC_VMAST m
INNER JOIN ACC_VDET d
ON (m.VM_PK = d.VM_PK)
INNER JOIN ACC_COA c
ON (c.COA_PK = d.COA_PK)
WHERE m.POST_BY IS NOT NULL
AND m.CANCEL_STATUS IS NULL
AND m.VM_DATE BETWEEN DATE '2021-07-06' AND DATE '2021-07-07'
AND d.COA_PK = '303'
ORDER BY
m.VM_DATE,
d.DEBIT;
You need to add a row range with "rows between unbounded preceding and current row".
sum(nvl(ACC_VDET.DEBIT,0) - nvl(ACC_VDET.CREDIT,0) )
over (order by ACC_VMAST.VM_DATE , ACC_VDET.DEBIT rows between unbounded preceding and current row ) running_bal

Oracle: Value from main query is not available in subquery

I have this query, and one of its column is a subquery that should be bringing a list of values using a listagg function. This list has its starting point as the S.ID_ORGAO_INTELIGENCIA value. The list is a should be, it always has values.
The listagg function is consuming an inline view that uses a window function to create the list.
select *
from (
SELECT DISTINCT S.ID_SOLICITACAO,
S.NR_PROTOCOLO_SOLICITACAO,
S.DH_INCLUSAO,
S.ID_USUARIO,
U.NR_CPF,
OI.ID_MODULO,
OI.ID_ORGAO_INTELIGENCIA,
OI.NO_ORGAO_INTELIGENCIA,
R.ID_ATRIBUICAO,
P.ID_PERMISSAO,
1 AS TIPO_NOTIFICACAO,
(
select LISTAGG(oc6.ID_ORGAO_INTELIGENCIA || '-' || oc6.ord || '-', '; ') WITHIN GROUP (ORDER BY oc6.ord) eai
from (
SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
oc1.SG_ORGAO_INTELIGENCIA,
rownum as ord
FROM TB_ORGAO_INTERNO oc1
WHERE oc1.DH_EXCLUSAO is null
-- THE VALUE FROM S.ID_ORGAO_INTELIGENCIA IS NOT AVAILBLE HERE
START WITH oc1.ID_ORGAO_INTELIGENCIA = S.ID_ORGAO_INTELIGENCIA
CONNECT BY prior oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA
) oc6) aproPrec
FROM TB_SOLICITACAO S
INNER JOIN TB_ORGAO_INTERNO OI ON S.ID_ORGAO_INTELIGENCIA = OI.ID_ORGAO_INTELIGENCIA
INNER JOIN TB_RELACIONAMENTO_ATRIBUICAO R
ON (R.ID_MODULO = OI.ID_MODULO AND R.ID_ORGAO_INTELIGENCIA IS NULL AND
R.ID_SOLICITACAO IS NULL)
INNER JOIN TB_PERMISSAO P
ON (P.ID_USUARIO = :usuario AND P.ID_ORGAO_INTELIGENCIA = :orgao AND
P.ID_ATRIBUICAO = R.ID_ATRIBUICAO)
INNER JOIN TB_USUARIO U ON (U.ID_USUARIO = S.ID_USUARIO)
WHERE 1 = 1
AND U.DH_EXCLUSAO IS NULL
AND P.DH_EXCLUSAO IS NULL
AND S.DH_EXCLUSAO IS NULL
AND OI.DH_EXCLUSAO IS NULL
AND R.ID_ATRIBUICAO IN :atribuicoes
AND P.ID_STATUS_PERMISSAO = 7
AND OI.ID_MODULO = 1
AND S.ID_STATUS_SOLICITACAO IN (1, 2, 5, 6)
and s.ID_ORGAO_INTELIGENCIA in (SELECT DISTINCT o.ID_ORGAO_INTELIGENCIA
FROM TB_ORGAO_INTERNO o
WHERE o.DH_EXCLUSAO IS NULL
START WITH o.ID_ORGAO_INTELIGENCIA = 3
CONNECT BY PRIOR o.ID_ORGAO_INTELIGENCIA = o.ID_ORGAO_INTELIGENCIA_PAI)
);
The problem is that the aproPrec column is always returning null as its result.
If I force the criteria to have the S.ID_ORGAO_INTELIGENCIA hardcoded, the list returns its true value.
If I chance this:
START WITH oc1.ID_ORGAO_INTELIGENCIA = S.ID_ORGAO_INTELIGENCIA
To this:
START WITH oc1.ID_ORGAO_INTELIGENCIA = 311
where 311 is the value that the S.ID_ORGAO_INTELIGENCIA column really has.
Is there a way to make this query works as 'I think' it should work?
To make it work, I changed the subquery by this another one:
(
select qt_.*
from (
SELECT QRY_NAME.*,
rownum as ord
FROM (
SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
connect_by_root (oc1.ID_ORGAO_INTELIGENCIA) as root
FROM TB_ORGAO_INTERNO oc1
CONNECT BY NOCYCLE PRIOR oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA
) QRY_NAME
WHERE root = s.ID_ORGAO_INTELIGENCIA
) qt_
)

Issue With GROUP BY In Query

First of all, thanks in advance for any help anyone can offer!
I'm fairly new to Oracle, so I apologize if this question is stupid...
I'm having an issue getting a query to run properly, and the issue is with the GROUP BY clause in the query.
When running the query, I get the error stating that it's not a GROUP BY statement?? Not really sure what that means.
Here is the query:
with SUB_GRP_LVL_1 as
(
select sg.HCC_ID,sge.SUB_GROUP_NAME
from XXXX_ODS.GROUP_T g
Join XXXX_ODS.SUB_GROUP sg
on g.GROUP_KEY=sg.GROUP_KEY
and g.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and sg.REC_SRC_CD='HS1'
and sg.LEVEL_NBR=1
join XXXX_ODS.SUB_GROUP_EFF sge
on sge.SUB_GROUP_KEY=sg.SUB_GROUP_KEY
---and sge.CURRENT_INDC=1
and sge.ACTIVE_INDC=1
)
,
SUB_GRP_LVL_2 as
(
select sg.HCC_ID,sge.SUB_GROUP_NAME
from XXXX_ODS.GROUP_T g
Join XXXX_ODS.SUB_GROUP sg
on g.GROUP_KEY=sg.GROUP_KEY
and g.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and sg.REC_SRC_CD='HS1'
and sg.LEVEL_NBR=2
join XXXX_ODS.SUB_GROUP_EFF sge
on sge.SUB_GROUP_KEY=sg.SUB_GROUP_KEY
and sge.ACTIVE_INDC=1
)
,
GRP_BEN_PL_ID as
(
select sg.SUB_GROUP_KEY,bpe.HCC_BENEFIT_PLAN_ID , sgbp.EFFECTIVE_DT, sgbp.EXPIRATION_DT, pe.FUNDING_TYPE, pe.HCC_PROD_ID, pe.STATE_CD, pe.SUB_COMPANY
from XXXX_ODS.GROUP_T g
Join XXXX_ODS.SUB_GROUP sg
on g.GROUP_KEY=sg.GROUP_KEY
and g.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and g.REC_SRC_CD='HS1'
JOIN XXXX_ODS.SUB_GROUP_BENEFIT_PLAN sgbp
on sg.SUB_GROUP_KEY=sgbp.SUB_GROUP_KEY
---and sgbp.CURRENT_INDC=1
and sgbp.ACTIVE_INDC=1
join XXXX_ODS.BENEFIT_PLAN_EFF bpe
on sgbp.BENEFIT_PLAN_KEY = bpe.BENEFIT_PLAN_KEY
and bpe.ACTIVE_INDC=1
join XXXX_ods.product_eff pe
on bpe.PRODUCT_KEY=pe.product_key
and pe.ACTIVE_INDC=1
)
select
BLK_1.SUB_GROUP_KEY,ACCT_NBR AS GROUPID,
SUB_GRP_ID,
DIVISION_ID
,GRP_BEN_PL_ID.HCC_BENEFIT_PLAN_ID
,INVOICE_NBR
,'CMD' BUSTYPE,
GRP_BEN_PL_ID.FUNDING_TYPE AS BUSSUBTYPE,
GRP_BEN_PL_ID.HCC_PROD_ID AS PROCODE,
'' AS PREMIUMTYPE,
INV.CURRENT_INVOICED_AMT AS PREMIUMBILLED,
INV.CURRENT_INVOICED_AMT AS PREMIUMDUEDATE,
'' AS PREMIUMPAID,
'' AS PREMIUMAPPLYDATE,
COUNT(invl.INVOICE_LINE_KEY) AS CONTRACTSXXXXL,
'' AS MEMBERSXXXXL
--ACCOUNT_TYPE
,DECODE (UPPER(GRP_BEN_PL_ID.STATE_CD),'NEBRASKA','NE','IOWA','IA') STATE,
GRP_BEN_PL_ID.SUB_COMPANY LGL_ENTITY,
LEVEL_NBR
from
(
select
g.GROUP_KEY, sg.SUB_GROUP_KEY, g.HCC_ID ACCT_NBR,ge.GROUP_NAME ACCT_NAME,substr(sg.HCC_ID, 1,instr(sg.hcc_id,'-',1,2)-1) SUB_GRP_ID,sg.HCC_ID DIVISION_ID,ce.FIRST_EFFECTIVE_DT,
add_months(
decode(ce.EFFECTIVE_DT,TO_DATE('01/01/1800','MM/DD/YYYY'),ce.FIRST_EFFECTIVE_DT,ce.EFFECTIVE_DT),ce.RENEWAL_INTERVAL) RENVL_DT, ce.ACCOUNT_TYPE
, sg.LEVEL_NBR
from
XXXX_ODS.CUSTOMER_EFF ce
join XXXX_ODS.GROUP_T g
on g.CUSTOMER_KEY=ce.CUSTOMER_KEY
Join XXXX_ODS.SUB_GROUP sg
on g.GROUP_KEY=sg.GROUP_KEY
and g.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and g.REC_SRC_CD='HS1'
and sg.LEVEL_NBR=2
and g.HCC_ID not like 'TEST%'
join XXXX_ODS.GROUP_EFF ge
on ge.GROUP_KEY = g.GROUP_KEY
and ge.CURRENT_INDC=1
union
select
gp.GROUP_KEY,
sgp.SUB_GROUP_KEY, gp.HCC_ID ACCT,gep.GROUP_NAME, sgp.HCC_ID SUB_GRP, NULL DIVISION,cep.FIRST_EFFECTIVE_DT,
add_months(decode(cep.EFFECTIVE_DT,TO_DATE('01/01/1800','MM/DD/YYYY'),cep.FIRST_EFFECTIVE_DT,cep.EFFECTIVE_DT),cep.RENEWAL_INTERVAL) RENVL_DT,
cep.ACCOUNT_TYPE, sgp.LEVEL_NBR
from
XXXX_ODS.CUSTOMER_EFF cep
join XXXX_ODS.GROUP_T gp
on gp.CUSTOMER_KEY=cep.CUSTOMER_KEY
Join XXXX_ODS.SUB_GROUP sgp
on gp.GROUP_KEY=sgp.GROUP_KEY
and gp.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and gp.REC_SRC_CD='HS1'
and sgp.LEVEL_NBR=1
and gp.HCC_ID not like 'TEST%'
join XXXX_ODS.GROUP_EFF gep
on gep.GROUP_KEY = gp.GROUP_KEY
and gep.CURRENT_INDC=1
and not exists
(
select 'X'
from
XXXX_ODS.GROUP_T gi
Join XXXX_ODS.SUB_GROUP sgi
on gi.GROUP_KEY=sgi.GROUP_KEY
and gi.HCC_ID NOT IN('A0002','A0003','A0004','A0005','A0021','A0022','A0041','A0042','A0081','A0121','A0061')
and gi.REC_SRC_CD='HS1'
and sgi.LEVEL_NBR=2
and gi.HCC_ID not like 'TEST%'
where
gp.HCC_ID=gi.HCC_ID
and sgp.HCC_ID=substr(sgi.HCC_ID, 1,instr(sgi.hcc_id,'-',1,2)-1)
)
) BLK_1
join SUB_GRP_LVL_1
on SUB_GRP_LVL_1.HCC_ID=BLK_1.SUB_GRP_ID
left join SUB_GRP_LVL_2
on SUB_GRP_LVL_2.HCC_ID=BLK_1.DIVISION_ID
left join GRP_BEN_PL_ID
on GRP_BEN_PL_ID.SUB_GROUP_KEY=BLK_1.SUB_GROUP_KEY
LEFT Join XXXX_ODS.INVOICE inv
on inv.BILL_TO_GROUP_KEY = BLK_1.GROUP_KEY
LEFT JOIN XXXX_ODS.INVOICE_BILLING_CATEGORY invbc
on invbc.INVOICE_KEY = inv.INVOICE_KEY
LEFT JOIN XXXX_ODS.INVOICE_LINE invl
on invl.INVOICE_BILLING_CATEGORY_KEY = invbc.INVOICE_BILLING_CATEGORY_KEY
GROUP BY
GRP_BEN_PL_ID.SUB_GROUP_KEY,
ACCT_NBR, --AS GROUPID,
SUB_GRP_ID,
DIVISION_ID
,GRP_BEN_PL_ID.HCC_BENEFIT_PLAN_ID
,INVOICE_NBR
,BUSTYPE
,GRP_BEN_PL_ID.FUNDING_TYPE,
,GRP_BEN_PL_ID.HCC_PROD_ID --AS PROCODE,
,PREMIUMTYPE
,INV.CURRENT_INVOICED_AMT
PREMIUMBILLED,
INV.CURRENT_INVOICED_AMT --AS PREMIUMDUEDATE,
,PREMIUMPAID
,PREMIUMAPPLYDATE
,MEMBERSXXXXL
ACCOUNT_TYPE
,STATE_CD,
GRP_BEN_PL_ID.SUB_COMPANY,
,LEVEL_NBR
order by ACCT_NBR,SUB_GRP_ID,LEVEL_NBR,DIVISION_ID
;
Thanks!
NEW ANSWER BASED ON COMMENT
Sorry I should have looked a bit closer I read the statement 'I get the error stating that it's not a GROUP BY statement' saw the count and made an assumption with my original answer.
With the further information provided in the comments I think the issue is actually that you are using the column alias in the group by.
When grouping you actually have to use the field names not the alias, if you have a static value (in this case '' AS MEMBERSXXXXL) you do not need to group by it SO
incorrect select using alias in the group by
select column1, column2 || column 3 as test2, '' as test, count(1) as cnt
from table
group by column1, test2, test
correct select omitting static value and putting full field in the group by
select column1, column2 || column 3 as test2, '' as test, count(1) as cnt
from table
group by column1, column2 || column 3
ORIGINAL ANSWER BELOW
where you have a count, min, max, sum ect within your select statement you need to tell it how to group the other columns....
you have
COUNT(invl.INVOICE_LINE_KEY) AS CONTRACTSXXXXL,
This means you will need a group by clause on your select.
Good resource for basics of this is
https://www.oracletutorial.com/oracle-basics/oracle-group-by/

ORA-01427: Subquery returns more than one row

When I execute the query below, I get the message like this: "ORA-01427: Sub-query returns more than one row"
Define REN_RunDate = '20160219'
Define MOP_ADJ_RunDate = '20160219'
Define RID_RunDate = '20160219'
Define Mbr_Err_RunDate = '20160219'
Define Clm_Err_RunDate = '20160219'
Define EECD_RunDate = '20160219'
select t6.Member_ID, (Select 'Y' from MBR_ERR t7 where t7.Member_ID = t6.Member_ID and t7.Rundate = &Mbr_Err_RunDate ) Mbr_Err,
NVL(Claim_Sent_Amt,0) Sent_Claims, Rejected_Claims,Orphan_Claim_Amt,Claims_Accepted, MOP_Adj_Sent Sent_MOP_Adj,Net_Sent,
(Case
When Net_Sent < 45000 then 0
When Net_Sent > 25000 then 20500
Else
Net_Sent - 45000
End
)Net_Sent_RI,
' ' Spacer,
Total_Paid_Claims CMS_Paid_Claims, MOP_Adjustment CM_MOP_Adj, MOP_Adjusted_Paid_claims CM_Net_Claims, Estimated_RI_Payment CM_RI_Payment
from
(
select NVL(t3.Member_ID,t5.Member_ID)Member_ID, t3.Claim_Sent_Amt, NVL(t4.Reject_Claims_Amt,0) Rejected_Claims, NVL( t8.Orphan_Amt,0) Orphan_Claim_Amt,
(t3.Claim_Sent_Amt - NVL(t4.Reject_Claims_Amt,0) - NVL(t8.Orphan_Amt,0)) Claims_Accepted,
NVL(t2.MOP_Adj_Amt,0) MOP_Adj_Sent ,
( (t3.Claim_Sent_Amt - NVL(t4.Reject_Claims_Amt,0)) - NVL(t2.MOP_Adj_Amt,0) - NVL(t8.Orphan_Amt,0) ) Net_Sent,
t5.Member_ID CMS_Mbr_ID,t5.Total_Paid_Claims,t5.MOP_Adjustment, t5.MOP_Adjusted_Paid_Claims, t5.Estimated_RI_Payment
From
(
Select t1.Member_ID, Sum( t1.Paid_Amount) Claim_Sent_Amt
From RENS t1
where t1.rundate = &REN_RunDate
group by t1.Member_ID
) t3
Left Join MOP_ADJ t2
on (t3.Member_ID = t2.Member_ID and t2.rundate = &MOP_ADJ_RunDate)
Left Join
(select Member_ID, sum(Claim_Total_Paid_Amount) Reject_Claims_Amt from CLAIM_ERR
where Rundate = &Claim_Err_RunDate
and Claim_Total_Paid_Amount != 0
Group by member_ID
)t4
on (t4.Member_ID = t3.Member_ID )
Full Outer Join
(
select distinct Member_ID,Total_Paid_Claims,MOP_Adjustment,MOP_Adjusted_Paid_Claims, Estimated_RI_Payment
from RID
where Rundate = &RID_RunDate
and Estimated_RI_Payment != 0
)t5
On(t5.Member_ID = t3.Member_ID)
Left Outer Join
(
select Member_ID, Sum(Claim_Paid_Amount) Orphan_Amt
From EECD
where RunDate = &EECD_RunDate
group by Member_ID
)t8
On(t8.Member_ID = t3.Member_ID)
)t6
order by Member_ID
You have this expression among the select columns (at the top of your code):
(Select 'Y' from MBR_ERR t7 where t7.Member_ID = t6.Member_ID
and t7.Rundate = &Mbr_Err_RunDate ) Mbr_Err
If you want to select the literal 'Y', then just select 'Y' as Mbr_Err. If you want to select either 'Y' or null, depending on whether the the subquery returns exactly one row or zero rows, then write it that way.
I suspect this subquery (or perhaps another one in your code, used in a similar way) returns more than one row - in which case you will get exactly the error you got.

PostgreSQL and filtered recursive query

There is an ability to query tree in Oracle with clauses CONNECT BY and START WITH.
For example:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id;
The query result can be simply filtered to show the only nodes which accepted by filter predicate or located on the path to root:
SELECT RPAD (' ', (LEVEL - 1) * 4) || node_name AS node, LEVEL
FROM hierarchy
START WITH NVL (pig_ear_id, 0) = 0
CONNECT BY PRIOR id = pig_ear_id AND id IN (
SELECT id
FROM hierarchy
START WITH node_name = 'some-pattern'
CONNECT BY PRIOR pig_ear_id = id
);
A similar select in PostgreSQL will be built with clause WITH RECURSIVE .... As I understand one with-query can not be included in other with-query to get same filtered result as Oracle allows.
How to rewrite the second select in PostgreSQL?..
As I understand one with-query can not be included in other with-query
Of course you can, just write one after the other:
with recursive valid_nodes as (
-- this is the inner "CONNECT BY" query from your example
select id
from hierarchy
where node_name = 'some-pattern'
union all
select c.id
from hierarchy c
join valid_nodes p on c.id = p.pig_ear_id
), final_tree as (
-- this is outer query from your example
select node_name as node, 1 as level
from hierarchy
where NVL (pig_ear_id, 0) = 0
union all
select c.node_name, p.level + 1
from hierarchy c
join final_tree p on p.id = c.pig_ear_id
where id in (select id from valid_nodes) -- and here we re-use the previous CTE
)
select rpad(node, level - 1)||node, level
from final_tree;
Note the recursive keyword only needs to be stated at the beginning. Regardless on how many recursive CTEs you have (but you need to have at least one in the CTE chain, if you use it).
If you have a with query that is calling some function and that function in turn has a with query,
then it allows us and not raise any error...in that way we still able to have nested with query.
so typically i created a query using with clause. see the first query below.
It has in clause which has select query that is selecting records returned by the functions(my_function).
and the function has another hierarchical with query.
Also i do not know what you want to return from your query.so change query as u need.This is just the way to achieve required structure.
Below is the syntax for sql server.Change appropriately for any other database.
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where pig_ear_id = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.pig_ear_id = b.id
and id in (select id from my_function('some-pattern')))
select * from alias_list;
==============================================================
create function my_function(#node_name varchar(40))
returns #temptable table
(
id varchar(40)
)
as
begin
with alias_list
(
pig_ear_id,
node_name,
id
) as (
select pig_ear_id, node_name, id
from hierarchy
where node_name = ?
union all
select b.pig_ear_id, node_name, id
from alias_list a, hierarchy b
where a.id = b.pig_ear_id)
insert into #temptable select * from alias_list;
return
end
================================================================

Resources