Search code examples
oracle-databaseplsqldeveloper

Oracle- count the number rows based on a condition


I want to create a 'ticket' which counts the number of passes for each ID. When we have a gold pass on any of the ID, this means the pass is applied to all those in booking. So for this example, we want to count 5. For the other pass_codes, we want to simply count the number of passes and exclude those that are nulls. I have an expected output below.

Say I have this data:

 Passes
    ID   | GuestID |  Pass_code
    ----------------------------
    100  |   001   | Bronze 
    100  |   002   | Bronze 
    101  |   103   | Gold
    101  |   104   | NULL
    101  |   105   | NULL
    101  |   106   | NULL
    101  |   107   | NULL
    102  |   208   | Silver
    103  |   209   | Steel
    103  |   210   | Steel
    103  |   211   | NULL
    
    Passengers
    ID   |  Passengers
    -----------------
    100  |  2
    101  |  5
    102  |  1
    103  |  3
    

I want to count then create a ticket in the output of:

    ID 100 | 2 pass (bronze)
    ID 101 | 5 pass (because it is gold, we count all passengers)
    ID 102 | 1 pass (silver)
    ID 103 | 2 pass (steel) (2 passes rather than than 3 as we just want to count only the passes for steel, bronze silver)

I want to do something like this, but as a combined query.

DECLARE @ID = 101; -- i will want to pass in IDs 

   -- for gold, we want to count all passengers when the gold pass is on 
   SELECT pp.Passengers
                 FROM passes
                 JOIN Passengers pp ON p.ID = pp.ID
                 WHERE p.pass_code IN'%gold%'
                 AND PP.id = @id

  -- for bronze, silver and steel
  SELECT 
       count(p.ID)
  FROM Passes
  WHERE p.ID = @id
  AND P.pass_code IN ('Bronze', 'silver', 'steel') -- Dont want to check based on NUlls as this may chnage to something else.

)

Any help or advice would be much appreciated.


Solution

  • Does this work for you?

    with Passes as (
    select  100 as id, 001  as guestid, 'Bronze' as passcode from dual union all
    select  100 as id, 002  as guestid, 'Bronze' as passcode from dual union all
    select  101 as id, 103  as guestid,'Gold'   as passcode from dual union all
    select  101 as id, 104  as guestid, NULL   as passcode from dual union all
    select  101 as id, 105  as guestid, NULL   as passcode from dual union all
    select  101 as id, 106  as guestid, NULL   as passcode from dual union all
    select  101 as id, 107  as guestid, NULL   as passcode from dual union all
    select  102 as id, 208  as guestid, 'Silver' as passcode from dual union all
    select  103 as id, 209  as guestid, 'Steel'  as passcode from dual union all
    select  103 as id, 210  as guestid, 'Steel'  as passcode from dual union all
    select  103 as id, 211  as guestid, NULL   as passcode from dual
    )
    SELECT 
      id,passcode,count(ID)
      FROM Passes
      where passcode is not null and passcode<>'Gold'
      group by id,passcode
       union all
     SELECT 
         id,'Gold',count(ID)
      FROM Passes
      where id in 
       (
      select id from Passes where  passcode='Gold' 
      ) 
      group by id
      order by id
    

    result:

    100 Bronze  2
    101 Gold    5
    102 Silver  1
    103 Steel   2