Skip to Main Content
  • Questions
  • 2 level subqueyries and problem select function result

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Mourad.

Asked: September 21, 2016 - 7:08 am UTC

Last updated: October 11, 2016 - 12:40 am UTC

Version: 11

Viewed 1000+ times

You Asked

Hello everybody,
I've 2 problems with on 2 queries :
1) The following query
with pres as ( 
              select t1.IDPROD AS spe1 , t2.IDPROD AS spe2 ,t1.INDICELIGNEPRESCRIPTION as id_ligne_1,t2.INDICELIGNEPRESCRIPTION as id_ligne_2,
                    case when t1.TYPEPROD = 5 then 1 else 0 end as typ_prod_1, 
                    case when t2.TYPEPROD =5 then 1 else 0 end as typ_prod_2
                    from PRESCRIPTIONS t1
                    inner join PRESCRIPTIONS t2 on (t1.IDPROD <> t2.IDPROD and t1.ID_ANALYSE = t2.ID_ANALYSE)
                    where  t1.ID_ANALYSE = 1 AND (t1.datedebut is null or t1.datefin is null
                                                or t2.datedebut is null or t2.datefin is null
                                                or ((t1.datedebut <= t2.datefin) and (t1.datefin >= t2.datedebut))
                                                or ((t2.datedebut <= t1.datefin) and (t2.datefin >= t1.datedebut))
                                                )
        )
SELECT  'Q' as ID_TYPE_ALERTE, pres1.*,  t3.FIC_CODE_SQ_PK as ID_FIC_IC, t3.FIC_TEXTE as TEXTE
FROM FIC_INCOMPATIBILITE t3, 
pres pres1, 
pres pres2
WHERE pres1.spe1 <> pres2.spe2 and t3.FIC_TYPE  = 'I'
AND t3.FIC_CODE_SQ_PK IN (  
                          SELECT t1.IC1SP_FIC_CODE_FK_PK
                          FROM IC1SP_TERME1SPECIALITE t1
                          inner join ( select IC2SP_FIC_CODE_FK_PK 
                                      from IC2SP_TERME2SPECIALITE ic2
                                      where ic2.IC2SP_SP_CODE_FK_PK = pres2.spe2 ) t2 on t1.IC1SP_FIC_CODE_FK_PK = t2.IC2SP_FIC_CODE_FK_PK
                          WHERE t1.IC1SP_SP_CODE_FK_PK = pres1.spe1          
                          UNION
                          SELECT t1.IC2SP_FIC_CODE_FK_PK
                          FROM (select IC2SP_FIC_CODE_FK_PK from IC2SP_TERME2SPECIALITE where IC2SP_SP_CODE_FK_PK = pres1.spe1) t1
                          inner join IC1SP_TERME1SPECIALITE t2 on t1.IC2SP_FIC_CODE_FK_PK = t2.IC1SP_FIC_CODE_FK_PK
                          WHERE  t2.IC1SP_SP_CODE_FK_PK = pres2.spe2 
         );
returns
ORA-00904: "PRES2"."SPE2": invalid identifier
error. I've searched and found that Oracle don't permiss 2 level of subqueries. But I'm forced to preserve this structure. In fact, I'm using the "pres" records to retreive the results.

Can anyone tell me how to change this query ?

2) The second problm is on the following query
Select 'B' as ID_TYPE_ALERTE, GET_REFERENCE_URL(1, fcpmsp.FCPMSP_SP_CODE_FK_PK, fcpmfich.FCPM_CODE_SQ_PK, 'C', fcpmter.FCPMTER_CDF_TER_CODE_FK_PK, fcpmter.FCPMTER_NATURE_CIPEMG_PK, fcpmter.FCPMTER_NUMSEQ_PK) as TEXTE 
   from FCPM_FICHECIPEMG fcpmfich
   inner join FCPMSP_CIPEMG_SPE fcpmsp on fcpmsp.FCPMSP_FCPM_CODE_FK_PK = fcpmfich.FCPM_CODE_SQ_PK
   inner join SP_SPECIALITE sp on fcpmsp.FCPMSP_SP_CODE_FK_PK = sp.sp_code_sq_pk
   inner join PRESCRIPTIONS PRE on (fcpmsp.FCPMSP_SP_CODE_FK_PK = PRE.IDPROD and PRE.ID_ANALYSE = ID_ANALYSE )   
   inner join FCPMTER_FCPM_TERRAIN fcpmter on fcpmter.FCPMTER_FCPM_CODE_FK_PK = fcpmfich.FCPM_CODE_SQ_PK
   inner join CDFPF_LIEN_CDF_PERE_FILS cdfpf on (fcpmter.FCPMTER_CDF_TER_CODE_FK_PK = cdfpf.CDFPF_CODEF_FK_PK 
                and cdfpf.CDFPF_NUMEROF_FK_PK = 'CS' 
                AND cdfpf.CDFPF_NUMEROP_FK_PK = 'TP')
   LEFT join CDF_CODIF cdf1 on (cdfpf.CDFPF_CODEP_FK_PK = cdf1.CDF_CODE_PK and cdf1.CDF_NUMERO_PK = cdfpf.CDFPF_NUMEROP_FK_PK)
   Left join CDF_CODIF cdf2 on (fcpmter.FCPMTER_CDF_TER_CODE_FK_PK = cdf2.CDF_CODE_PK and cdf2.CDF_NUMERO_PK = 'CS')
   where fcpmter.fcpmter_nature_cipemg_pk in (select * from the (select cast(in_list(nature_cipemg) as mytabletype) from dual ))

The problem is that I'm selecting the result of a function (GET_REFERENCE_URL)but Data are empty for the colomn TEXTE. Also, in this query I'm forced to use union to select CLOB data but as you know Oracle dont' permiss this. Unsign union all gives dupllicated records and I'cant do a dinstint on CLOB Data. Can anyone tell how to proceed ?

Many thanks in advance for your help.
Best regard.

and Chris said...

1. I don't understand why you need a subquery in this join:

select t1.ic1sp_fic_code_fk_pk
from ic1sp_terme1specialite t1
inner join
  (select ic2sp_fic_code_fk_pk
  from ic2sp_terme2specialite ic2
  where ic2.ic2sp_sp_code_fk_pk = pres2.spe2
  ) t2
on t1.ic1sp_fic_code_fk_pk   = t2.ic2sp_fic_code_fk_pk


Surely you can replace it with something like:

select t1.ic1sp_fic_code_fk_pk
from ic1sp_terme1specialite t1
inner join ic2sp_terme2specialite ic2
on ic2.ic2sp_sp_code_fk_pk = pres2.spe2
and t1.ic1sp_fic_code_fk_pk   = t2.ic2sp_fic_code_fk_pk;


thus avoiding the need to join 2 levels deep?

2. You can return one of the clobs by using dbms_lob.compare to find the matching values in a subquery, then filtering to return the min of these:

create table t (
  x clob
);
insert into t values ('clob');
insert into t values ('clob');
insert into t values ('blah');

select distinct x from t;

SQL Error: ORA-00932: inconsistent datatypes: expected - got CLOB

select x from t t
where  rowid in (
  select min(rowid)from t s
  where  dbms_lob.compare(t.x, s.x) = 0
);

X     
clob  
blah  

Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Mourad HEDFI, September 22, 2016 - 9:26 am UTC

Many thanks for your response. But integrating your solution for the first query does't resolve the problem.
After correction, the query is
with pres as ( 
              select /*+ MATERIALIZE */ t1.IDPROD AS spe1 , t2.IDPROD AS spe2 ,t1.INDICELIGNEPRESCRIPTION as id_ligne_1,t2.INDICELIGNEPRESCRIPTION as id_ligne_2,
                    case when t1.TYPEPROD = 5 then 1 else 0 end as typ_prod_1, 
                    case when t2.TYPEPROD =5 then 1 else 0 end as typ_prod_2
                    from PRESCRIPTIONS t1
                    inner join PRESCRIPTIONS t2 on (t1.IDPROD <t2.IDPROD and t1.ID_ANALYSE = t2.ID_ANALYSE)
                    where  t1.ID_ANALYSE = 1 AND t1.IDPROD <> t2.IDPROD 
                    and (t1.datedebut is null or t1.datefin is null
                        or t2.datedebut is null or t2.datefin is null
                        or ((t1.datedebut <= t2.datefin) and (t1.datefin >= t2.datedebut))
                        or ((t2.datedebut <= t1.datefin) and (t2.datefin >= t1.datedebut))
                       )
        )
SELECT  'Q' as ID_TYPE_ALERTE, pres1.*,  t3.FIC_CODE_SQ_PK as ID_FIC_IC, t3.FIC_TEXTE as TEXTE
FROM FIC_INCOMPATIBILITE t3, 
pres pres1,
pres pres2
WHERE t3.FIC_TYPE  = 'I'
AND t3.FIC_CODE_SQ_PK in ( select ic1.ic1sp_fic_code_fk_pk
                           from ic1sp_terme1specialite ic1
                           inner join ic2sp_terme2specialite ic2 on ic2.ic2sp_sp_code_fk_pk = pres2.spe2
                                                                and ic1.ic1sp_fic_code_fk_pk   = ic2.ic2sp_fic_code_fk_pk 
                           union
                           select ic2.IC2SP_FIC_CODE_FK_PK
                           from IC2SP_FIC_CODE_FK_PK ic2
                           inner join IC1SP_TERME1SPECIALITE ic1 on ic2.IC2SP_SP_CODE_FK_PK = pres1.spe1 
                                                                and ic2.IC2SP_FIC_CODE_FK_PK = ic1.IC1SP_FIC_CODE_FK_PK 
         );
and I've always
ORA-00904: "PRES2"."SPE2": invalid identifier

Do you have an idea what is wrong ?
Chris Saxon
September 22, 2016 - 11:38 pm UTC

Could you give us the create table statements so we can reproduce this ourselves?

Mourad HEDFI, September 26, 2016 - 11:33 am UTC

Many Thanks for reponse. You find below the tables script to let you to exectue the query :
CREATE TABLE "FIT_FICHEINTERAC" 
   ( "FIT_CODE_SQ_PK" NUMBER(6,0), 
 "FIT_ORIGINE" CHAR(1), 
 "FIT_DATECR" DATE, 
 "FIT_DATEMJ" DATE, 
 "FIT_TEXTE" CLOB
   );
   
CREATE TABLE "IT1SP_TERME1SPECIALITE" ("IT1SP_FIT_CODE_FK_PK" NUMBER(6,0), "IT1SP_SP_CODE_FK_PK" NUMBER(6,0));
ALTER TABLE "IT1SP_TERME1SPECIALITE" ADD CONSTRAINT "FK_IT1SP_FIT" FOREIGN KEY ("IT1SP_FIT_CODE_FK_PK") REFERENCES "FIT_FICHEINTERAC" ("FIT_CODE_SQ_PK") ON DELETE CASCADE ENABLE;

CREATE TABLE "IT2SP_TERME2SPECIALITE" ("IT2SP_FIT_CODE_FK_PK" NUMBER(6,0), "IT2SP_SP_CODE_FK_PK" NUMBER(6,0));
ALTER TABLE "IT2SP_TERME2SPECIALITE" ADD CONSTRAINT "FK_IT2SP_FIT" FOREIGN KEY ("IT2SP_FIT_CODE_FK_PK") REFERENCES "FIT_FICHEINTERAC" ("FIT_CODE_SQ_PK") ON DELETE CASCADE ENABLE;

CREATE TABLE PRESCRIPTIONS (
 ID_ANALYSE     INT NOT NULL,
 INDICELIGNEPRESCRIPTION  INT NOT NULL,
 DATEDEBUT      DATE,
 DATEFIN      DATE,
 IDPROD       VARCHAR2(20),
 TYPEPROD      INTEGER,
 CONTENANCE_UD     VARCHAR2(20),
 UNITE_CONTENANCE    VARCHAR2(30),
 VECTEUR_INJ      VARCHAR2(200),
 MATERIAU_CONT_INJ    VARCHAR2(100),
 CONSTRAINT PRESCRIPTIONS_PK PRIMARY KEY (ID_ANALYSE, INDICELIGNEPRESCRIPTION)
);

Chris Saxon
September 27, 2016 - 8:37 am UTC

Thanks, but we're missing the definitions of some tables! FIC_INCOMPATIBILITE, ic2sp_fic_code_fk_pk are in the query too...

Mourad HEDFI, September 27, 2016 - 12:16 pm UTC

Many Thakns for your response and sorry for the mistake. You find below the query tables DDL
CREATE TABLE FIC_INCOMPATIBILITE
(
  FIC_CODE_SQ_PK Integer NOT NULL,
  FIC_ORIGINE Char(1) NOT NULL,
  FIC_TYPE  Char(1) NOT NULL,
  FIC_TEXTE Clob ,
  FIC_DATECR Date NOT NULL,
  FIC_DATEMJ Date,
  CONSTRAINT PK_FIC_INCOMPATIBILITE PRIMARY KEY (FIC_CODE_SQ_PK)
);


CREATE TABLE IC1SP_TERME1SPECIALITE
(
  IC1SP_FIC_CODE_FK_PK Integer NOT NULL,
  IC1SP_SP_CODE_FK_PK Integer NOT NULL,
  CONSTRAINT PK_IC1SP_TERME1SPECIALITE PRIMARY KEY (IC1SP_FIC_CODE_FK_PK,IC1SP_SP_CODE_FK_PK)
);

ALTER TABLE IC1SP_TERME1SPECIALITE ADD CONSTRAINT FK1_IC1SP_TERME1SPECIALITE
  FOREIGN KEY (IC1SP_FIC_CODE_FK_PK) REFERENCES FIC_INCOMPATIBILITE (FIC_CODE_SQ_PK) ON DELETE CASCADE ENABLE;

CREATE TABLE IC1SP_TERME1SPECIALITE
(
  IC1SP_FIC_CODE_FK_PK Integer NOT NULL,
  IC1SP_SP_CODE_FK_PK Integer NOT NULL,
  CONSTRAINT PK_IC1SP_TERME1SPECIALITE PRIMARY KEY (IC1SP_FIC_CODE_FK_PK,IC1SP_SP_CODE_FK_PK)
);

ALTER TABLE IC1SP_TERME1SPECIALITE ADD CONSTRAINT FK1_IC1SP_TERME1SPECIALITE
  FOREIGN KEY (IC1SP_FIC_CODE_FK_PK) REFERENCES FIC_INCOMPATIBILITE (FIC_CODE_SQ_PK) ON DELETE CASCADE;

CREATE TABLE PRESCRIPTIONS (
 ID_ANALYSE     INT NOT NULL,
 INDICELIGNEPRESCRIPTION  INT NOT NULL,
 DATEDEBUT      DATE,
 DATEFIN      DATE,
 IDPROD       VARCHAR2(20),
 TYPEPROD      INTEGER,
 CONTENANCE_UD     VARCHAR2(20),
 UNITE_CONTENANCE    VARCHAR2(30),
 VECTEUR_INJ      VARCHAR2(200),
 MATERIAU_CONT_INJ    VARCHAR2(100),
 CONSTRAINT PRESCRIPTIONS_PK PRIMARY KEY (ID_ANALYSE, INDICELIGNEPRESCRIPTION)
);

Chris Saxon
October 10, 2016 - 8:52 am UTC

Sorry, but there's still some tables missing from the DDL...

IC1SP_TERME1SPECIALITE appears twice.

IC2SP_FIC_CODE_FK_PK is in your from clause but not defined as a table (perhaps this is part of the issue?)

Mourad HEDFI, October 10, 2016 - 10:46 am UTC

Thanks for response. In fact, it's a mistake when pasting the IC2 DDL.
You find it below :
CREATE TABLE IC2SP_TERME2SPECIALITE
(
  IC2SP_FIC_CODE_FK_PK Integer NOT NULL,
  IC2SP_SP_CODE_FK_PK Integer NOT NULL,
  CONSTRAINT PK_IC2SP_TERME2SPECIALITE PRIMARY KEY (IC2SP_FIC_CODE_FK_PK,IC2SP_SP_CODE_FK_PK)
);
ALTER TABLE IC2SP_TERME2SPECIALITE ADD CONSTRAINT FK1_IC2SP_TERME2SPECIALITE
  FOREIGN KEY (IC2SP_FIC_CODE_FK_PK) REFERENCES FIC_INCOMPATIBILITE (FIC_CODE_SQ_PK) ON DELETE CASCADE;

Chris Saxon
October 10, 2016 - 1:57 pm UTC

The most recent version of your query has:

select ic2.IC2SP_FIC_CODE_FK_PK
from IC2SP_FIC_CODE_FK_PK ic2


Note IC2SP_FIC_CODE_FK_PK as the table name!

What should the query be?

one suggestion

Ravi B, October 10, 2016 - 4:05 pm UTC

A friendly suggestion so that we could save time and effort in resolving and getting answers to our problems. We all are busy, so why not do this and respect each others time.

This would be a good start.

https://dl.dropboxusercontent.com/u/9171666/asktom/good_question.jpg

Before posting a "reproducible" test case, i think it is a good idea to execute the statements ourselves so that they will not bomb with syntax errors.

Please remember we are getting FREE advice by someone who has proven expertise in the field and are investing their time trying to help us.

They do not know our

1) business rules
2) schema design
3) table structures, indexes etc
4) expected outcome

Is this information too much to ask?
Chris Saxon
October 11, 2016 - 12:40 am UTC

"Is this information too much to ask? "

often it appears that it is :-)

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here