Multiple case statements with aggregates- SQL

Hi guys
Here is my ddl
create table TestTable
  Bill_date                    DATE,
  Phone_no                     NUMBER(10),
  Planlvl1                     VARCHAR2(20),
  Planlvl2                     VARCHAR2(20)
  Revenue                      NUMBER                     
INSERT INTO TestTable
Values
('1/01/2014' , 64221, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014'' , 64221, 'Bundle', 'PlanA', '$32'),
('1/01/2014' , 65211, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 65211, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014' , 66211, 'Bundle', 'PlanB', '$34'),
('1/01/2014' , 66211, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 66222, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014' , 66222, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 66222, 'Bundle', 'PlanB', '$65'),
('1/01/2014' , 32444, 'Non_bundle', 'Casual1', '$32'),
('1/01/2014' , 324441, 'Non_bundle', 'Casual2', '$76'),
('1/01/2014' , 65444, 'Non_bundle', 'Casual1', '$12'),
('1/01/2014' , 65444, 'Bundle', 'PlanB', '$98'),
('1/01/2014' , 54322, 'Bundle', 'PlanA', '$12'),
('1/01/2014' , 54322, 'Non_bundle', 'Casual', '$12')
Expected Outcome:
Bill_date PlanLvl2 PhonenoCount
'01/01/2014' 'SpecialPack1' 1
'01/01/2014' 'SpecialPack2' 3
'01/01/2014' 'Casual1' 1
'01/01/2014' 'Casual2' 1
'01/01/2014' 'PlanA' 1
'01/01/2014' 'PlanB' 1
Basically I have to count all the phone nos grouped by plans in a certain way:
If PlanLvl1 = Bundle, then I have to look  at planLvl2 and see if that phone no has ' SpecialPack%' ,and also another plan,them 'Special pack' gets the priority and the phone no gets counted in the special pack.
In case when PlanLvl1 = Bundle and a phone no has both 'Special Packs' as their plans, then the phone no will be counted under the 'Special Pack' with higher Revenue.
In case where PalnLvl is 'Bundle' and a phone no has multiple 'Special Packs' and a non special, that ph no will only be counted once under 'Special Pack; of higher rev as compared to the special pack of lower rev.
Now there are also PlanLvl1 which are 'Non_Bundles' which means they do not have any 'SpecialPacks' but if a ph no with 'NonBundle' plan has 2 different plans under planLvl2, we need to count that ph no for eack planLvl2..
Then there is a scenario where a ph no can have bundles as well as non bundles and in that case we just have to count that ph no in bundles and not in non-bundles.
As I mentioned , 'SpecialPack2' will get a preference over special pack 1 if a phone no has got both of these
Hope this helps

I;m not sure exactly what your rules are since you specify both "In case when PlanLvl1 = Bundle and a phone no has both 'Special Packs' as their plans, then the phone no will be counted under the 'Special Pack' with higher Revenue" and "As I mentioned ,
'SpecialPack2' will get a preference over special pack 1 if a phone no has got both of these".  I went with the rule "As I mentioned , 'SpecialPack2' will get a preference over special pack 1 if a phone no has got both of these" since that seemed to match
the result you say you want.  I also changed the datatypes to valid SQL Server datatypes.
create table TestTable
Bill_date DATE,
Phone_no Decimal(10,0),
Planlvl1 VARCHAR(20),
Planlvl2 VARCHAR(20),
Revenue money
INSERT INTO TestTable
Values
('1/01/2014' , 64221, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014' , 64221, 'Bundle', 'PlanA', '$32'),
('1/01/2014' , 65211, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 65211, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014' , 66211, 'Bundle', 'PlanB', '$34'),
('1/01/2014' , 66211, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 66222, 'Bundle', 'SpecialPack1', '$23'),
('1/01/2014' , 66222, 'Bundle', 'SpecialPack2', '$3'),
('1/01/2014' , 66222, 'Bundle', 'PlanB', '$65'),
('1/01/2014' , 32444, 'Non_bundle', 'Casual1', '$32'),
('1/01/2014' , 324441, 'Non_bundle', 'Casual2', '$76'),
('1/01/2014' , 65444, 'Non_bundle', 'Casual1', '$12'),
('1/01/2014' , 65444, 'Bundle', 'PlanB', '$98'),
('1/01/2014' , 54322, 'Bundle', 'PlanA', '$12'),
('1/01/2014' , 54322, 'Non_bundle', 'Casual', '$12')
;With cte As
(Select Bill_date, Phone_no, Planlvl1, Planlvl2, Revenue,
Row_Number() Over (Partition By Bill_Date, Phone_no Order By
Case When Planlvl1 = 'Bundle' And Planlvl2 Like 'SpecialPack2' Then 0 Else 1 End,
Case When Planlvl1 = 'Bundle' And Planlvl2 Like 'SpecialPack1' Then 0 Else 1 End,
Case When Planlvl1 = 'Bundle' Then Revenue Else -1 End Desc) As rn,
Min(Case When Planlvl1 = 'Bundle' Then 0 Else 1 End) Over(Partition By Bill_Date, Phone_no) As NumberHasOnlyNonBundle
From TestTable)
Select Bill_date, Planlvl2, COUNT(*) As PhoneNoCount
From cte
Where rn = 1 Or NumberHasOnlyNonBundle = 1
Group By Bill_date, Planlvl2;
Tom

Similar Messages

  • Help with multiple case statements

    Hello,
    I am new to BO.  I am on XI 3.0.  SQL 2005.  In Designer, I am trying to create a measure in a financial universe that would end up being multiple case statements within one select.  This is what I tried to do, but it doesn't work with the two case statements.  Can I use an ELSE leading into the second CASE WHEN somehow?  How can I accomplish this?  Sorry for my ignorance!
    CASE WHEN dbo.ClientBudgetYear.DateStage1Approved > 01/01/1900 AND dbo.ClientBudgetMonth.Month = 12 THEN dbo.ClientBudgetMonth.Stage1Sales END
    CASE WHEN  dbo.ClientBudgetYear.DateStage1Approved > 01/01/1900 AND dbo.ClientBudgetMonth.Month = 11 THEN dbo.ClientBudgetMonth.Stage1Sales END
    Any Suggestions?
    Thanks,
    Holly

    Holly,
    I don't know enough about your data or requirement to provide a solution, however, the construct that you post will not work because it causes you to build an object with multiple case statements when only one case statement per object is permitted.  From what I see in your code I would be inclined to combine the two statements into one as such:
    CASE WHEN dbo.ClientBudgetYear.DateStage1Approved > 01/01/1900 AND dbo.ClientBudgetMonth.Month in (11,12) THEN dbo.ClientBudgetMonth.Stage1Sales else null END
    Thanks,
    John

  • Executing multiple DDL statements with OracleCommand

    hi..
    im having trouble executing multiple ddl statements with the the oracle command object. i have tried to enclose them within Begin.. End; block but with no use.
    this problem seems to occur only with DDL statements,.. as my DML like update, delete and Inserts seem to work fine when enclosed within the PL /SQL block.
    single DDL statements also seem to work fine. so im guessing this has nothing to do with priviledges. any ideas?
    my code as follows
    OracleCommand command = new OracleCommand();
    command.CommandType = CommandType.Text;
    command.CommandText = string.Format(@"{0}",script);
    conn.Open();
    command.Connection = conn;
    command.ExecuteNonQuery();
    the script is read from a file, and looks like this. (note : i have removed any line breaks or any other characters)
    BEGIN ALTER TABLE SYSTEMUSER DISABLE CONSTRAINT FK_USER_CLIENT; ALTER TRIGGER SET_SUBSCRIPTION_SUB_I DISABLE; END;
    this is the error i get.
    Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 7:
    PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
    begin case declare exit for goto if loop mod null pragma
    raise return select update while with <an identifier>
    <a double-quoted delimited-identifier> <a bind variable> <<
    close current delete fetch lock insert open rollback
    savepoint set sql execute commit forall merge pipe.

    If I'm not mistaken, we're not allowed to issue DDL inside anonymoue block (or stored procedure) since DDL has implicit commit in it. But you still can execute DDL using EXECUTE IMMEDIATE or using DBMS_SQL package. Try changing your CommandText like this,
    BEGIN
       EXECUTE IMMEDIATE 'ALTER TABLE SYSTEMUSER DISABLE CONSTRAINT FK_USER_CLIENT';
       EXECUTE IMMEDIATE 'ALTER TRIGGER SET_SUBSCRIPTION_SUB_I DISABLE';
    END;Hope this helps,
    [Nur Hidayat|http://nur-hidayat.net/]

  • How to optimized Multiple CASE statement

    Hi..
    Somebody please help me out to use most optimized Multiple CASE statement in below example.. 
    Select
    CAST(COUNT(DISTINCT(CASE WHEN period_id <350 THEN period_id END)) AS DECIMAL(30,0))  AS Column1,                  CAST(COUNT(DISTINCT(CASE WHEN period_id >=351 AND period_id<=375 THEN period_id END))
    AS DECIMAL(30,0)) AS Column2,                                
    CAST(COUNT(DISTINCT(CASE WHEN period_id >=376 AND period_id<=400 THEN period_id END)) AS DECIMAL(30,0)) AS Column3,                             
    CAST(COUNT(DISTINCT(CASE WHEN period_id >=401 AND period_id<=450 THEN period_id END)) AS DECIMAL(30,0)) AS Column4,                             
    CAST(COUNT(DISTINCT(CASE WHEN period_id >=451 AND period_id<=575 THEN period_id END)) AS DECIMAL(30,0)) AS Column5,
    CAST(COUNT(DISTINCT(CASE WHEN pmc ='UVS' THEN pmc END)) AS DECIMAL(30,0)) AS Column6,                                
    CAST(COUNT(DISTINCT(CASE WHEN pmc ='VAL' THEN pmc END)) AS DECIMAL(30,0)) AS Column7                            
    FROM [Table1]
    Thanks in Advance,
    Deepak Goyal

    How is an index going to help in a query with no where clause or join?
    Rhetorical question but it brings to light the problem.  This query is going to produce a table/index scan precisely because there's no where clause.
    You need to change the way you are thinking about the problem.  The problem isn't that you need a better performing case statement, the problem is that you need to minimize the number of records you ask SQL Server to read from disk.  You do that
    by using a where clause or by joining to a smaller table.
    Here's one option which should give you the desired results while performing much better:
    create index idx_period_id on Table1 (period_id)
    create index idx_pmc on Table1 (pmc) include (period_id)
    select (select count(distinct period_id) from Table1 where period_id < 350) as Column1,
    (select count(distinct period_id) from Table1 where period_id between 351 and 375) as Column2,
    (select count(distinct period_id) from Table1 where period_id between 376 and 400) as Column3,
    (select count(distinct period_id) from Table1 where period_id between 401 and 450) as Column4,
    (select count(distinct period_id) from Table1 where period_id between 451 and 575) as Column5,
    (select count(distinct period_id) from Table1 where pmc = 'UVS') as Column6,
    (select count(distinct period_id) from Table1 where pmc = 'VAL') as Column7

  • How to create nested CASE statements in PL/SQL

    Can anyone please tell how to create Nested CASE statements in PL/SQL with proper syntax?
    It would be better if you can help with an example.
    Thank you!

    Something like this:
    SQL> set serveroutput on
    SQL> declare
      2    v1 number := 2;
      3    v2 varchar2(1) := 'C';
      4  begin
      5    case v1
      6      when 1 then dbms_output.put_line('First');
      7      when 2 then begin
      8                    case v2
      9                      when 'A' then dbms_output.put_line('Found A');
    10                      when 'B' then dbms_output.put_line('Found B');
    11                      when 'C' then dbms_output.put_line('Found C');
    12                      else dbms_output.put_line('NONE');
    13                    end case;
    14                  end;
    15      else dbms_output.put_line('Else');
    16    end case;
    17  end;
    18  /
    Found C
    PL/SQL procedure successfully completed
    SQL> If you have further doubts regarding syntax you can read the docs on the Case statement here:
    http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/case_statement.htm

  • Case statement with having null gives default result

    Hello,
    When we write a case statement with a not equal condition <> on a column and if that columns has null value the it gives the else value.
    eg
    Select Column_Name, Case when Column_Name <>Condition then 0 else 1 end as case_test from Table_Name.
    Ideally null is not equal to the condition so the case should return 0 but it returns 1. Can anyone tell me why?

    In addition to the other posts:
    NULL is an unknown value, when you say
      col <> 1
    and col is NULL, we don't know whether col is 1 or something else. Thus the condition evaluates to UNKNOWN. How UNKNOWN is handled depends on the context. In WHEN clauses as well as the IF statments, the effect that the code bracketed by IF/WHEN is not
    entered. That is, UNKNOWN and FALSE yields the same result. In CHECK constraints, it's the other way round. If you have
     CHECK (WHEN col <> 0)
    rows where col is NULL are accepted.
    When you work with SQL, no matter the database product, it's imperative to master three-valued logic, because it comes up all the time.
    As I said, NULL is the unknown value. In practice, NULL has a distinct interpreation depending on the database column. For instance, NULL in a column called EndDate, usually means that the period (or whatever it is) is still open. So often when you work
    with NULL values you use isnull to replace it with some value that fits the context, and finding that value takes some consideration. Blindly doing isnull(col, '') can lead to serious bugs, particularly if col is not a string column.
    Erland Sommarskog, SQL Server MVP, [email protected]

  • Case statement in advanced sql

    how to use case statement in advanced sql.Example if quarter=1 i need to select jan,fev,and march months from table

    this is the case statement i am using :
    case when 1=@{quarter} then substring(cast((etxnmis.month_year) as char) from 5 for 2) IN ('03', '04', '05') else null end
    and i get the below error
    : HY000. Code: 10058. [NQODBC] [SQL_STATE: HY000] [nQSError: 10058] A general error has occurred. [nQSError: 27002] Near <IN>: Syntax error [nQSError: 26012] . (HY000)

  • Case statement with Subquery

    Case statement with Subquery
    select case when condition then
    i want to execute qr1
    else qr2
    How to implement this ?

    Hi,
    Welcoem to the forum!
    972471 wrote:
    Case statement with SubqueryHow does a sub-query, or a query, figure in this question?
    Be more specific. Post a complete script that you tried, and what output you expected from it. If you got an error, post the complete error message, including line numbers.
    See the forum FAQ {message:id=9360002}
    select case when condition then
    i want to execute qr1
    else qr2
    How to implement this ?Here's one way:
    BEGIN
        CASE
            WHEN  1 = 1
            THEN
                dbms_output.put_line ('Condition was TRUE');
            ELSE
                dbms_output.put_line ('Condition was FALSE or UNKNOWN');
        END CASE;
    END;
    /If the condition involves a query, then you may have to select the results into a variable first, and then use the variable in the CASE statement.

  • Multiple Select statements in EXECUTE SQL TASK in SSIS

    Can we write multiple select statements in execute sql task(SSIS).
    If possible how to assign them to variables in result statement

    Hi ,
    You can use below steps to set result set to variable.
    1.In the Execute SQL Task Editor dialog box, on the General page, select the Single row, Full result set, or XML result set type(According to your result set).
    2.Click Result Set.
    3.To add a result set mapping, click Add.
    4.From the Variables Name list, select a variable or create a new variable.
    What is multiple selection ? May be below can be used in your scenario !
    http://stackoverflow.com/questions/17698908/how-to-set-multiple-ssis-variables-in-sql-task
    What you want to achieve ?
    Thanks
    Please Mark This As Answer or vote for Helpful Post if this helps you to solve your question/problem. http://techequation.com

  • Help: How to include logic in multiple CASE statements.

    Hello Folks,
    I have this Query where am converting from Access to Oracle. Am little confused on how to write multiple CASE statements.Apprecitae your help.
        round(Sum(IIf(recovery_flg = 'NONCASH FEE RECEIVED',
                         IIf(feepaid < FEE, FEE - FEEPAID, FEE),
                         0)),
                 2)

    *(1) you can nest CASE* - CASE in a CASE
    CASE WHEN ecovery_flg = 'NONCASH FEE RECEIVED' THEN
         CASE WHEN feepaid < FEE THEN ....
         END
    ENDor
    *(2) you can try to rewrite it as one CASE*
    CASE WHEN ecovery_flg = 'NONCASH FEE RECEIVED' AND feepaid < FEE THEN...
         WHEN ecovery_flg = 'NONCASH FEE RECEIVED' AND feepaid >= FEE THEN ...
    END

  • Help With A Case Statement With Multiple Variables

    I apologize if this is the incorrect Forum for this type of question, but it was the closest one that I could find. I'm pretty new with SQL and am stuck on this issue. I have roughly 26 dates that I need to compare to one another. Each date is tied to a step code. I also have a Stop value that is tied directly to the "max date" of the step codes. So, I need to compare 30 dates against one another to 1st - ID the max date; 2nd - ID if the Stop value is correct; 3rd - if the stop value is incorrect, identify what the correct value would be.
    At first, this seemed like it wouldn't be that hard. I wrote a query that found the max date for each step code. Then I realized that multiple step codes could have the same date. So, I tried using this case statement, but I did not get the expected results. Is there a more efficient way of getting what I need? This code seems like it's not necessary and probably the source of my issue.
    CASE
    WHEN FS25.ACTUAL_COMPLETION_DATE > FS.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS1.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS2.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS3.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS4.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS5.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS6.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS7.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS8.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS9.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS10.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS11.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS12.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS13.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS14.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS15.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS16.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS17.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS18.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS19.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS20.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS21.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS22.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS23.ACTUAL_COMPLETION_DATE AND FS25.ACTUAL_COMPLETION_DATE > FS24.ACTUAL_COMPLETION_DATE AND L.FORECLOSURE_STOP_CODE <= '8' THEN '9'
    ELSE 'UH OH'
    END AS "CHANGE FC STOP TO"
    Any assistance is appreciated!

    I think Igor pointed out a working solution before.
    Applying it at your examples (you missed the operator after STOP_CODE, I assume it =):
    CASE
    WHEN FS25 = GREATEST(FS25, FS24, FS23) AND STOP_CODE = '9' THEN '9'
    ELSE 'UH OH'
    END AS 'CHANGE STOP CODE TO'
    {code}
    Be careful at the second example. You are checking:
    {code:sql}
    FS25 > FS24 OR FS25 IS NOT NULL AND FS24 IS NULL AND FS25 > FS23
    OR
    FS25 IS NOT NULL AND FS23 IS NULL AND STOP_CODE = '9'
    {code}
    Remember that AND has higher priority among operators than OR so if FS25 is greater than FS24 and FS23 the condition will be true even if STOP_CODE is not equal 9.
    Regards.
    Al                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Creating Multiple INSERT statements with SQL

    is there a way to create multiple INSERT staements with SQL .
    Example scenario : This is only example but i have lot of data in the real time.
    sql : Select Emplid from Table A where Emplid between 100 and 350 will retun me 50 rows . i want to insert those rows into another table.
    I am looking for output like below instead of Giving output just as EMPLIDs
    Insert into PS_LM_DATA ( EMPLID ) values ( 123 )
    Insert into PS_LM_DATA ( EMPLID ) values ( 234 )
    Insert into PS_LM_DATA ( EMPLID ) values ( 334 )
    and so on....
    thanks ,
    Karu

    If you are inserting into another table, you could use
    insert into PS_LM_DATA ( EMPLID ) 
    select Emplid from Table A where Emplid between 100 and 350Example:
    SQL> insert into emp2(empno) select empno from emp;
    14 rows created.
    SQL> insert into emp2(empno) select empno from emp where empno between 7369 and 7788;
    8 rows created.

  • Sql case statement with link not opening new window

    Apex 4.2
    I am writing a query that has a case statement. I need the case statement to open up a new window, not a new tab. I have the following:
    SELECT
    case when SCHED_ID = 1 then
    '<a href="javascript:popupURL(''http://www.google.com'')">LINK</a>'
    end as MyLink
    FROM Table_Name
    When I plug this into a a column link in the URL field under a page item or report item, then a popup window appears. However, inside the query I am getting a new tab.
    ANy help on this matter would be great. Thanks in advance.

    Hi,
    Try adding a target attribute to you link:
    '<a href="javascript:popupURL(''http://www.google.com'')" target="_blank">LINK</a>' 
    Regards,
    Vincent

  • Case Statement with Group By

    Hello,
    I am trying to build a query that returns the 3 months of a quarter. Below are the two case statements that I am trying to use. I am getting a "Not a group by expression" in the first case statement, and a "nota a single-group group function in the second. Any help with this would be appreciated.
    Thanks, sck10
    SELECT Trev.Revenue_Year,
    CASE
    WHEN Trev.Revenue_Name = 'Jan' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Apr' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Jul' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Oct' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    ELSE SUM(0)
    END AS Month_01,
    CASE
    WHEN Trev.Revenue_Name = 'Feb' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'May' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Aug' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Nov' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    ELSE SUM(0)
    END AS Month_02,
    CASE
    WHEN Trev.Revenue_Name = 'Mar' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Jun' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Sep' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    WHEN Trev.Revenue_Name = 'Dec' THEN Round(SUM(COALESCE(Trev.Revenue, 0)), 1)
    ELSE SUM(0)
    END AS Month_03
    FROM Stage_Report_Revenue Trev
    GROUP BY Trev.Revenue_Year;
    SELECT Trev.Revenue_Year,
    SUM(CASE
    WHEN Trev.Revenue_Name = 'Jan' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Apr' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Jul' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Oct' THEN COALESCE(Trev.Revenue, 0)
    ELSE 0
    END) AS Month_01,
    SUM(CASE
    WHEN Trev.Revenue_Name = 'Feb' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'May' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Aug' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Nov' THEN COALESCE(Trev.Revenue, 0)
    ELSE 0
    END) AS Month_02,
    SUM(CASE
    WHEN Trev.Revenue_Name = 'Mar' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Jun' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Sep' THEN COALESCE(Trev.Revenue, 0)
    WHEN Trev.Revenue_Name = 'Dec' THEN COALESCE(Trev.Revenue, 0)
    ELSE SUM(0)
    END) AS Month_03
    FROM Stage_Report_Revenue Trev
    GROUP BY Trev.Revenue_Year;

    You are getting the "Not a group by expression" error because you are not using in aggregate functions in your select statement. (You are using the aggregate function SUM in the second query)
    The "not a a single-group group function" means you are returning multiple rows of a data when it only expects one.
    HTH

  • CASE statement in PL/SQL

    Hi PL/SQL experts,
    I'm going a bit loopy here, so could someone please point out what I'm doing wrong with this case statement:
    Test procedure is:
    CREATE OR REPLACE procedure SCOTT.postcode_validate_2 (input_post_code VARCHAR2) as
    alphabet_string VARCHAR2(52) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxwyz';
    number_string VARCHAR2(10) := '012345789';
    last_part_postcode VARCHAR2(3) := NULL;
    BEGIN
    IF INSTR(input_post_code,' ') = 0
    THEN
    DBMS_OUTPUT.PUT_LINE('We need a space in the postcode please');
    GOTO exit;
    ELSIF LENGTH(SUBSTR(input_post_code,instr(input_post_code,' ')+1)) > 3
    THEN
    DBMS_OUTPUT.PUT_LINE('Last part of postcode can only be 3 characters');
    GOTO exit;
    ELSE
    last_part_postcode := SUBSTR(input_post_code,instr(input_post_code,' ')+1);
    END IF;
    CASE input_post_code
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 2
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A9')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A9');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA9')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA9');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A99')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A99');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A9A')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A9A');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 4
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0
    AND instr(number_string,substr(input_post_code,4,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA99')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA99');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 4
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,4,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA9A')
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA9A');
    -- GOTO exit;
    -- END IF;
    END;
    -- Check last part of format, should be AA9
    IF (instr(number_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('End part of the postcode is in the correct format, 9AA');
    ELSE
    DBMS_OUTPUT.PUT_LINE('End part of the postcode is in the wrong format!');
    END IF;
    <<exit>>
    DBMS_OUTPUT.PUT_LINE('Please try again');
    END;
    However, I'm getting the following error:
    LINE/COL ERROR
    37/6 PLS-00103: Encountered the symbol "WHEN" when expecting one of
    the following:
    := . ( % ;
    On a second note, can I not have the ELSE structure embedded within the case (currently commented out)?
    Thanks very much in advance.
    Dev

    Fixed code:
    CREATE OR REPLACE procedure postcode_validate_2 (input_post_code VARCHAR2) as
    alphabet_string VARCHAR2(52) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxwyz';
    number_string VARCHAR2(10) := '012345789';
    last_part_postcode VARCHAR2(3) := NULL;
    BEGIN
    IF INSTR(input_post_code,' ') = 0
    THEN
    DBMS_OUTPUT.PUT_LINE('We need a space in the postcode please');
    GOTO exit;
    ELSIF LENGTH(SUBSTR(input_post_code,instr(input_post_code,' ')+1)) > 3
    THEN
    DBMS_OUTPUT.PUT_LINE('Last part of postcode can only be 3 characters');
    GOTO exit;
    ELSE
    last_part_postcode := SUBSTR(input_post_code,instr(input_post_code,' ')+1);
    END IF;
    CASE
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 2
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A9');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A9');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA9');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA9');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A99');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A99');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 3
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(number_string,substr(input_post_code,2,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format A9A');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format A9A');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 4
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0
    AND instr(number_string,substr(input_post_code,4,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA99');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA99');
    -- GOTO exit;
    -- END IF;
    WHEN (length(substr(input_post_code,1,instr(input_post_code,' ')-1)) = 4
    AND instr(alphabet_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(number_string,substr(input_post_code,3,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,4,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('We have a valid postcode in the format AA9A');
    -- ELSE
    -- DBMS_OUTPUT.PUT_LINE('Sorry but that is an incorrect postcode! Format AA9A');
    -- GOTO exit;
    -- END IF;
    END CASE;
    -- Check last part of format, should be AA9
    IF (instr(number_string,substr(input_post_code,1,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,2,1)) != 0
    AND instr(alphabet_string,substr(input_post_code,3,1)) != 0)
    THEN
    DBMS_OUTPUT.PUT_LINE('End part of the postcode is in the correct format, 9AA');
    ELSE
    DBMS_OUTPUT.PUT_LINE('End part of the postcode is in the wrong format!');
    END IF;
    <<exit>>
    DBMS_OUTPUT.PUT_LINE('Please try again');
    END;
    /As VG2 pointed out you were missing some semicolons.
    Also, CASE input_post_code was replaced with just CASE since you are doing a searched case.
    Also, END at the end of the case statement was replaced with END CASE.

Maybe you are looking for