Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Trouble with Case Statement

Author  Topic 

vmchase
Starting Member

5 Posts

Posted - 2012-05-08 : 15:17:31
I am having problems with this case statement. I don't know what I am doing wrong but I get the error:

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

I have a case when the field equals a value then do a left outer join but if the field equals a different value then do a inner join. This is my query:

SELECT

case
when oqt = '26' then

(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
WHERE QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt)and active = 1)
END,
case
when oqt = '31' then
(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM inner join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
where QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt) and active = 1)

END
from tempoq

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-05-08 : 15:24:39
A CASE expression can only return one result. It appears you are trying to select multiple values.

Is there more too this query? It doesn't appear to be any relation from the outer most reference of the tempoq table and the inner references.

Perhaps posting some sampel data and expected output might help to clarify?
http://www.sqlservercentral.com/articles/Best+Practices/61537/
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-05-08 : 15:33:45
It might help if you describe what you are tryign to do in greater detail, but maybe you can make use of the UNION or UNION ALL operator?
Select 
qm.id_oqm,
cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName,
qm.methodName as actualMethod,
cv.*
FROM
OQMethods QM
left outer join
courseversions cv
on cv.evalid = QM.id_eval
and cv.courselanguage = 'EN'
and cv.courseactive='Y'
and cv.id_cp > 0
and QM.id_oqt = '26'
and active = 1

UNION

Select
qm.id_oqm,
cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName,
qm.methodName as actualMethod,
cv.*
FROM
OQMethods QM
inner join
courseversions cv
on cv.evalid = QM.id_eval
and cv.courselanguage = 'EN'
and cv.courseactive='Y'
and cv.id_cp > 0
where
QM.id_oqt = '31' and active = 1
Go to Top of Page

vmchase
Starting Member

5 Posts

Posted - 2012-05-08 : 15:47:46
What I am trying to do is if the oqt = 26 then the join has to be an left outer join, but if it is 31- it has to be a inner join. All other oqt numbers it would just select everything from the tempoq table. I am not sure how to go about writing an if statement on this since I can have mulitple value.
Go to Top of Page

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2012-05-08 : 16:36:41
quote:
Originally posted by vmchase

I am having problems with this case statement. I don't know what I am doing wrong but I get the error:

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

I have a case when the field equals a value then do a left outer join but if the field equals a different value then do a inner join. This is my query:

SELECT

case
when oqt = '26' then

(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
WHERE QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt)and active = 1)
END,
case
when oqt = '31' then
(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM inner join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
where QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt) and active = 1)

END
from tempoq




I'm not quite sure, if I understand the question right, but give this a try:

select a.is_oqm
,case(isnull(a.is_eval,'') as varchar(50))+' - '+a.methodname as methodname
,a.methodname as actualmethod
,c.*
from oqmethods as a
inner join tempoq as b
on b.oqt=a.id_oqt
left outer join courseversions as c
on c.evalid=a.is_eval
and c.courselanguage='EN'
and c.courseactive='Y'
and c.is_cp>0

where a.active=1
and case when c.evalid is null then 0 else 1 end>=case when b.oqt='31' then 1 else 0 end

This sql was not testet or even checked for syntax errors.
Go to Top of Page

vmchase
Starting Member

5 Posts

Posted - 2012-05-08 : 17:28:36
I maybe thinking to hard on this one,

But basically, I am selecting this:

Select qm.oqt, qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*

FROM OQMethods QM

But it's the joins that are conditional-

If the qm.oqt = 26 then I will have a left outer join
left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0

But if the qm.oqt = 31 then I will have a inner join
inner join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0

where QM.id_oqt in (SELECT tempoq.oqt FROM tempoq where tempoq.oqt = QM.id_oqt)and active = 1)

I just don't know how to script this in sql the correct way
Go to Top of Page

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2012-05-09 : 12:26:48
quote:
Originally posted by vmchase

I maybe thinking to hard on this one,

But basically, I am selecting this:

Select qm.oqt, qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*

FROM OQMethods QM

But it's the joins that are conditional-

If the qm.oqt = 26 then I will have a left outer join
left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0

But if the qm.oqt = 31 then I will have a inner join
inner join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0

where QM.id_oqt in (SELECT tempoq.oqt FROM tempoq where tempoq.oqt = QM.id_oqt)and active = 1)

I just don't know how to script this in sql the correct way




Use the sql I suggested earlier, and change the "where" section to

where a.active=1
and c.evalid in ('26','31')
and case when c.evalid is null then 0 else 1 end>=case when b.oqt='31' then 1 else 0 end

This will "simulate" inner joining when evalid=31 (I guess this is what you want?)
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-05-09 : 12:51:33
quote:
Originally posted by vmchase

What I am trying to do is if the oqt = 26 then the join has to be an left outer join, but if it is 31- it has to be a inner join. All other oqt numbers it would just select everything from the tempoq table. I am not sure how to go about writing an if statement on this since I can have mulitple value.

Again hard to tell without sample data and expected output. Bitsmed solution might work for you, but it sounds like you also want data for all other values of OQT. If that is true the logic get slightly more complicated.
Go to Top of Page

vmchase
Starting Member

5 Posts

Posted - 2012-05-09 : 14:19:39
Bitsmed solution worked for 26 and 31 but I need all the other values for OQT as well.
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-05-09 : 14:34:32
I'll say it again without sample data and expected output it really hard to help you. That having been said, maybe this WHERE clause will help?
where 
active = 1
AND
(
(
QM.id_oqt = '31'
AND cv.id IS NOT NULL-- Some ID or value that is not nullable from the courseversions table
)
OR
(
QM.id_oqt <> '31'
)
)
Go to Top of Page

bitsmed
Aged Yak Warrior

545 Posts

Posted - 2012-05-09 : 16:16:15
quote:
Originally posted by vmchase

Bitsmed solution worked for 26 and 31 but I need all the other values for OQT as well.


When my first reply to this thread should work for you.
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2012-05-09 : 16:41:00
quote:
Originally posted by vmchase

What I am trying to do is if the oqt = 26 then the join has to be an left outer join, but if it is 31- it has to be a inner join. All other oqt numbers it would just select everything from the tempoq table. I am not sure how to go about writing an if statement on this since I can have mulitple value.



Ah, a "Conditional Join" it sounds like; the key is to do BOTH joins and only use CASE (or something similar) to return what you need.

More here: http://weblogs.sqlteam.com/jeffs/archive/2007/04/03/Conditional-Joins.aspx

- Jeff
http://weblogs.sqlteam.com/JeffS
Go to Top of Page
   

- Advertisement -