简体   繁体   中英

Newbie SQL error; missing expression

Newbie to sql here

I am attempting return sa_id from the query below but I am getting a 'missing expression' error.

select s.sa_id
    from cisadm.ci_sa s
    where s.sa_status_flg = '20'
    and s.sa_type_cd = 'LEURIBIL'
    and s.sa_id in {
      select *
      from cisadm.ci_intv_pf pf
      where pf.intv_pf_typ_cd = 'SMPCHGRI'}
    ;

The sa_id exists in both tables; ci_sa and ci_intv_pf.

I need the sa_id to have a intv_pf_typ_cd of 'SMPCHGRI' in the ci_intv_pf table. And I need the matching sa_id to have an sa_type_cd of 'LEURIBIL' from the ci_sa table.

Have tried ending the query with group by and having but not having any luck.

Any help much appreciated

You can use a standard sub-query as you are attempting in your question;

SELECT s.sa_id
FROM   cisadm.ci_sa s
WHERE  s.sa_status_flg = '20'
AND    s.sa_type_cd = 'LEURIBIL'
AND    s.sa_id IN (SELECT pf.sa_id
                   FROM   cisadm.ci_intv_pf pf
                   WHERE  pf.intv_pf_typ_cd = 'SMPCHGRI')

A correlated sub-query is also possible using EXISTS:

SELECT s.sa_id
FROM   cisadm.ci_sa s
WHERE  s.sa_status_flg = '20'
AND    s.sa_type_cd = 'LEURIBIL'
AND    s.sa_id EXISTS (SELECT 1
                       FROM   cisadm.ci_intv_pf pf
                       WHERE  pf.intv_pf_typ_cd = 'SMPCHGRI'
                       AND    pf.sa_id = s.sa_id)

And then there's using WITH to refactor the sub-query which can make complex queries a bit easier to read;

WITH sub_query AS
(SELECT 1
 FROM   cisadm.ci_intv_pf pf
 WHERE  pf.intv_pf_typ_cd = 'SMPCHGRI')
SELECT  s.sa_id
FROM   cisadm.ci_sa s
       INNER JOIN 
       sub_query pf ON pf.sa_id = s.sa_id
WHERE  s.sa_status_flg = '20'
AND    s.sa_type_cd = 'LEURIBIL'

There will likely be some differences in efficiency for all these based largely on the relative sizes of the tables but Oracle does a pretty good job of picking the most efficient way nowadays.

Caveat: I haven't actually set up tables and data to test these

Just return the sa_id in the inner SQL:

select s.sa_id
    from cisadm.ci_sa s
    where s.sa_status_flg = '20'
    and s.sa_type_cd = 'LEURIBIL'
    and s.sa_id in (
      select pf.sa_id 
      from cisadm.ci_intv_pf pf
      where pf.intv_pf_typ_cd = 'SMPCHGRI')
    ;

Endorsing Prdp, however, please consider following code that is little bit faster as it reads count instead of values -

select s.sa_id
from cisadm.ci_sa s
where s.sa_status_flg = '20'
and s.sa_type_cd = 'LEURIBIL'
and exist (
                    select  1
                    from    cisadm.ci_intv_pf pf
                    where   pf.intv_pf_typ_cd = 'SMPCHGRI'
                    and s.sa_id = pf.sa_id
        );

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