Select Error in Case

I am getting a syntax error and not sure why near my select. I want to bring back fee1 if the 2nd When is true

CASE WHEN Len(c.FeeSchedule) < 3 THEN

CONVERT(int, c.feeSchedule)

WHEN Len(c.FeeSchedule) > 3 THEN

SELECT fd.Fee1 FROM FeeScheduleDetails fd

where c.feeSchedule = fd.code AND m.original BETWEEN fd.LowLimit AND fd.HighLimit

ELSE

CONVERT(int, c.feeSchedule)

END AS FeeSchedule,




Answer this question

Select Error in Case

  • akqajohn

    You can't do a select there because you need exactly one value. Perhaps using COALESCE and TOP 1 would work as in

    CASE WHEN Len(c.FeeSchedule) < 3 THEN

    CONVERT(int, c.feeSchedule)

    WHEN Len(c.FeeSchedule) > 3 THEN

    COALESCE(

    (SELECT TOP 1 fd.Fee1 FROM FeeScheduleDetails fd

    where c.feeSchedule = fd.code AND m.original BETWEEN fd.LowLimit AND fd.HighLimit), "")

    ELSE

    CONVERT(int, c.feeSchedule)

    END AS FeeSchedule,

    But if that doesn't work, I'm not sure how you'd fix it, you probably can't do it this way.



  • TnTico

    Thus it would be:

    CASE WHEN Len(c.FeeSchedule) < 3 THEN CONVERT(int, c.feeSchedule)

    WHEN Len(c.FeeSchedule) > 3 THEN

    fd.Fee1

    END,

    Clarity Consulting (http://www.claritycon.com)


  • Bernd VanSkiver

    OK - I did say it was a guess :-)

    The core problem is that you can't put a sub query in a case, because your when should only return one value. It looks like you can't do it at all, unless someone else has a better idea.



  • Don Peterson

    Hi,

    Shughes is right. Join in the table if you you need values from that table.

    If you don't have a relation to the records for all of your records use a left join. It seems to be what you are trying to accomplish with your case statement.

    Regards



  • nrs251

    but that query will never return more than one result. There is never a case where it may be between that range in 2 records' Lowlimt and Highlimit

    so are you saying even so, SQL doesn't like a select like that



  • ArtusKG

    There is a simple solution to this problem. You cannot haver a subquery within a CASE statement, regardless of whether it returns 1 value or not. Also, almost always never use TOP unless when producing reports. Otherwise, you cannot guarantee what value you with get returned if the data changes, or the db schema changes.

    There are two simple solutions

    1. JOIN the table in the CASE statement to the end of your query, then just select the Fee1 column in the CASE statement

    2. If you are only ever going to use one value from that table, regardless of what row you are in, then instead of 1, just get the value first and store it in a variable, then use that in the CASE statement instead.

    Much simpler. HTH

    Clarity Consulting


  • FiftyFeet

    CASE WHEN Len(c.FeeSchedule) < 3 THEN

    CONVERT(int, c.feeSchedule)

    WHEN Len(c.FeeSchedule) > 3 THEN

    COALESCE((SELECT TOP 1 fd.Fee1 FROM FeeScheduleDetails fd

    where c.feeSchedule = fd.code

    AND m.original BETWEEN fd.LowLimit AND fd.HighLimit), "")

    ELSE

    CONVERT(int, c.feeSchedule)

    END AS FeeSchedule,

    Errors:

    Msg 1038, Level 15, State 3, Procedure IT_Create_CurrentMonth_DCR_Data2, Line 26

    Cannot use empty object or column names. Use a single space if necessary.

    Msg 156, Level 15, State 1, Procedure IT_Create_CurrentMonth_DCR_Data2, Line 97

    Incorrect syntax near the keyword 'Select'.

    Msg 170, Level 15, State 1, Procedure IT_Create_CurrentMonth_DCR_Data2, Line 97

    Line 97: Incorrect syntax near ')'.

    Msg 156, Level 15, State 1, Procedure IT_Create_CurrentMonth_DCR_Data2, Line 100

    Incorrect syntax near the keyword 'ELSE'.

    Msg 156, Level 15, State 1, Procedure IT_Create_CurrentMonth_DCR_Data2, Line 191

    Incorrect syntax near the keyword 'END'.



  • blahmoo64

    Hi dba123,
     
    The SELECT statement has to be in parentheses, since it's a subquery:
     

    CASE WHEN Len(c.FeeSchedule) < 3 THEN

    CONVERT(int, c.feeSchedule)

    WHEN Len(c.FeeSchedule) > 3 THEN

    (SELECT fd.Fee1 FROM FeeScheduleDetails fd

    where c.feeSchedule = fd.code AND m.original BETWEEN fd.LowLimit AND fd.HighLimit)

    ELSE

    CONVERT(int, c.feeSchedule)

    END AS FeeSchedule,

     
    Note that you can simplfy this some more to
     

    CASE WHEN Len(c.FeeSchedule) <= 3 THEN

    CONVERT(int, c.feeSchedule)

    ELSE

    (SELECT fd.Fee1 FROM FeeScheduleDetails fd

    where c.feeSchedule = fd.code AND m.original BETWEEN fd.LowLimit AND fd.HighLimit)

    END AS FeeSchedule,

     
    Also note that you'll get run-time errors if the subquery returns more than one row. If that's the case, then you'll need to specify some extra criteria to narrow the results down to just one row.

    --
    Hugo Kornelis, SQL Server MVP
     

    I am getting a syntax error and not sure why near my select. I want to bring back fee1 if the 2nd When is true

    CASE WHEN Len(c.FeeSchedule) < 3 THEN

    CONVERT(int, c.feeSchedule)

    WHEN Len(c.FeeSchedule) > 3 THEN

    SELECT fd.Fee1 FROM FeeScheduleDetails fd

    where c.feeSchedule = fd.code AND m.original BETWEEN fd.LowLimit AND fd.HighLimit

    ELSE

    CONVERT(int, c.feeSchedule)

    END AS FeeSchedule,


  • devalapa_k

    I'm definately saying that even if the system were to parse your database and see this is the case, it would not be guarenteed to be the case in the future. TOP 1 can specify that you want only one value, you should always use it when you assume only one value will come back.

    But I'm still not sure you can use a query in a case, just if you can, it would need to look like that.



  • Select Error in Case