Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Nested Case Statement Syntax

Posted on 2013-01-03
8
Medium Priority
?
803 Views
Last Modified: 2013-01-03
I am trying to write a nested case statement to look back at the 3 prior months and give me an average. But I keep getting an error. Where am I wrong?



CASE
        WHEN LatestMonthNum=2
        THEN
            CASE
              WHEN MONTH(TodayDate)=1 and YEAR(TodayDate)=LatestYearNum or
              MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum -1 or
              MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1
               THEN ConvertedQuantity/3
             ELSE CASE WHEN LatestMonthNum=1 THEN
               CASE WHEN MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum-1 or
              MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1 or
              MONTH(TodayDate)=10 and YEAR(TodayDate)=LatestYearNum -1
               THEN ConvertedQuantity/3
              ELSE CASE WHEN MONTH(TodayDate)= LatestMonthNum-1 and YEAR(TodayDate)=LatestYearNum or MONTH(TodayDate)= LatestMonthNum-2 and YEAR(TodayDate)=LatestYearNum or MONTH(TodayDate)= LatestMonthNum-3 and YEAR(TodayDate)=LatestYearNum
             then ConvertedQuantity/3
             else null
           
             END as 'ThreeMoAvg'
0
Comment
Question by:nirajkrishna
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 38741767
Howdy...

Indenting the code makes it really easy to see.  :)

CASE WHEN LatestMonthNum=2
     THEN CASE WHEN MONTH(TodayDate)=1 and YEAR(TodayDate)=LatestYearNum or
                    MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum -1 or
                    MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1
               THEN ConvertedQuantity/3
               ELSE CASE WHEN LatestMonthNum=1 
                         THEN CASE WHEN MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum-1 or
                                        MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1 or
                                        MONTH(TodayDate)=10 and YEAR(TodayDate)=LatestYearNum -1
                                   THEN ConvertedQuantity/3
                                   ELSE CASE WHEN MONTH(TodayDate)= LatestMonthNum-1 and YEAR(TodayDate)=LatestYearNum or
                                                  MONTH(TodayDate)= LatestMonthNum-2 and YEAR(TodayDate)=LatestYearNum or 
                                                  MONTH(TodayDate)= LatestMonthNum-3 and YEAR(TodayDate)=LatestYearNum
                                             then ConvertedQuantity/3
                                             else null
                                   END as 'ThreeMoAvg' 

Open in new window



It's really tough to see what you're trying to achieve.  Can you explain it?  The SQL should be easy.  :)


Kent
0
 
LVL 66

Expert Comment

by:Jim Horn
ID: 38741769
<knee-jerk reaction>
I see AND and OR in the same clauses, but no parentheses ( ) to determine order of execution.  

I'm guessing the first block should be this:

CASE WHEN
    (MONTH(TodayDate)=1 and YEAR(TodayDate)=LatestYearNum) or
    (MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum -1) or
    (MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1)
      THEN ConvertedQuantity/3

Without the parentheses ( ), it's going to do each and .. or ... and as an entire set, and since Month(TodayDate) is likely a single value per row, it'll never evaluate as True and return the THEN expression, only the ELSE expression.
0
 

Author Comment

by:nirajkrishna
ID: 38741772
This is just the calculated column and not the whole query. I am cross joined to a single row table that gives me the most recent date and  latest month number (LatestMonthNum) and latest year (LatestYearNum)
0
Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

 
LVL 46

Accepted Solution

by:
Kent Olsen earned 2000 total points
ID: 38741792
Every CASE clause must have a matching END.  The indented code above shows that a few well placed END statements are needed.  I think that you want something like this, but it's hard to know.  Keep in mind that if a CASE statement doesn't find a match, NULL is returned so this may take some more work.

CASE WHEN LatestMonthNum=2
     THEN CASE WHEN MONTH(TodayDate)=1 and YEAR(TodayDate)=LatestYearNum or
                    MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum -1 or
                    MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1
               THEN ConvertedQuantity/3
          END
     ELSE CASE WHEN LatestMonthNum=1 
               THEN CASE WHEN MONTH(TodayDate)=12 and YEAR(TodayDate)=LatestYearNum-1 or
                              MONTH(TodayDate)=11 and YEAR(TodayDate)=LatestYearNum -1 or
                              MONTH(TodayDate)=10 and YEAR(TodayDate)=LatestYearNum -1
                         THEN ConvertedQuantity/3
                    END
          END
     ELSE CASE WHEN MONTH(TodayDate)= LatestMonthNum-1 and YEAR(TodayDate)=LatestYearNum or
                    MONTH(TodayDate)= LatestMonthNum-2 and YEAR(TodayDate)=LatestYearNum or 
                    MONTH(TodayDate)= LatestMonthNum-3 and YEAR(TodayDate)=LatestYearNum
               then ConvertedQuantity/3
               else null
          END
END as 'ThreeMoAvg' 

Open in new window

0
 

Author Comment

by:nirajkrishna
ID: 38741797
I am trying to say if the LatestMonthNum = 2 or 1 which means Jan or Feb then look at the latest month number and use the appropriate 3 prior months totals divided by 3 to give me an average. If it is not Jan or Feb then look at the data and when the month falls into the 3 prior months of today then add it to this column and divide it by 3 otherwise leave blank.


I am making a quick daily report that shows the current months performance (convertedQuantity) vs last month vs 3 prior month average.
0
 
LVL 15

Expert Comment

by:gplana
ID: 38741809
as kdo said, every case should finish with an end. Try to change your expression by the expression added by kdo
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 38741812
All that this complicated CASE statement does is divide ConvertedQuantity by 3.  Or not.

You probably want record selection (the WHERE filter) to determine which rows to process and just divide by 3.
0
 

Author Closing Comment

by:nirajkrishna
ID: 38742184
This worked perfectly except for at the end I had to add one more "END" before the "END AS". Thanks!
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you need a simple but flexible process for maintaining an audit trail of who created, edited, or deleted data from a table, or multiple tables, and you can do all of your work from within a form, this simple Audit Log will work for you.
When trying to connect from SSMS v17.x to a SQL Server Integration Services 2016 instance or previous version, you get the error “Connecting to the Integration Services service on the computer failed with the following error: 'The specified service …
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

704 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question