简体   繁体   中英

Use select clause in case expression to set condition

  1. Query 1
    select * from worklog where worklog.recordkey IN
       case 
       when worklog.class ='ACTIVITY'  THEN (SELECT wonum from woactivity where parent ='M2176' )
       when worklog.class ='WORKORDER' THEN  (SELECT WONUM FROM WORKORDER WHERE WONUM = 'M2176')
       end ;
  1. Query 2:
    SELECT * from worklog
       WHERE CASE WHEN worklog.class='ACTIVITY' THEN 
                       worklog.recordkey in (select wonum from woactivity where parent='M2176' ) 
             end
                  WHEN worklog.class='WORKORDER' THEN 
                       worklog.recordkey = (select wonum from workorder where wonum='M2176')  
             end  ;

in the above queries I need to set a value in worklog.recordkey. I have two conditions when worklog.class is 'ACTIVITY', I have to set vat value from WOACTIVITY wonum and if worklog.class is 'WORKORDER' then I have to set value from WORKORDER table. When I use the above queries I am getting Errors like:

'Incorrect syntax near the keyword 'in''

and

'Incorrect syntax near the keyword 'case''.

Please help me with this.

Because workorder is a table and woactivity is basically a view on that table where woclass = 'ACTIVITY' , you can simplify your query this way:

select * from worklog where
(class, recordkey, siteid) in (select woclass, wonum, siteid from workorder)
and wonum='M2176'

And if the above doesn't work for you on SQL Server, per @Dex's comment, just flip it around:

select * From worklog where
exists (select 1 from workorder wo where 
    wo.woclass = worklog.class
    and wo.siteid = worklog.siteid
    and wo.wonum = worklog.wonum)
and wonum='M2176'

Note that I have added siteid into the comparison mix, since workorder is at the site level of information.

Skip the case expression, use regular AND / OR instead:

SELECT * from worklog
WHERE (worklog.class = 'ACTIVITY' and
       worklog.recordkey in (select wonum from woactivity where parent='M2176')) 
   OR (worklog.class='WORKORDER' AND 
       worklog.recordkey = (select wonum from workorder where wonum='M2176'))

As mentioned above:

1) WORKORDER is a base table, and WOACTIVITY to a view of this table with a restriction based on the WORKORDER.WOCLASS attribute

2) The logical key for the WORKORDER object is SITEID + WONUM. ie a WONUM value may not be unique across the entire environment.

3) All records relating to a specific WORKORDER will have the same SITED + WOGROUP value.

4) The primary WORKORDER record will have ISTASK = 0 and WONUM = WOGROUP, while the associated activities will have ISTASK=1.

You don't need to use CASE . I think you can accomplish what you're trying to do with boolean operators

Query 1

select * from worklog where 
  (worklog.class ='ACTIVITY' 
    and worklog.recordkey in 
      (select wonum from woactivity where parent ='M2176'))
  OR
  (worklog.class ='WORKORDER'
    and worklog.recordkey in
      (select wonum from workorder where wonum = 'M2176'));

Query 2

Here, I also changed the second condition on worklog.recordkey , from = to in

    select * from worklog
       where (worklog.class='ACTIVITY'
               and worklog.recordkey in
                 (select wonum from woactivity where parent='M2176'))
          or (worklog.class='WORKORDER' 
               and worklog.recordkey in
                 (select wonum from workorder where wonum='M2176'))

You can do it with this too.

SELECT * 
FROM worklog w 
WHERE 1=1
    AND w.class = 'ACTIVITY' 
    AND w.recordkey IN (SELECT wonum FROM woactivity WHERE parent = 'M2176')
UNION ALL
SELECT * 
FROM worklog w 
WHERE 1=1
    AND w.class = 'WORKORDER' 
    AND w.recordkey IN (SELECT wonum FROM workorder WHERE parent = 'M2176')

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