sqloracle-databaseora-00979

Odd 'GROUP BY' error in a sub-query while using Oracle


A quick background -- I need to find the termination rates of cases that go through our company lab grouped by case type and month. So far I came up with this:

SELECT BPI.TYPE,
       EXTRACT(MONTH FROM CS.RECEIVED_DATE) MONTH,
       COUNT(*) termed_cases
  FROM CELL_SOURCE cs
  JOIN BASIC_PATHOLOGY_INFO bpi ON CS.CELL_SOURCE_ID = BPI.CELL_SOURCE_ID
  JOIN RECENT_CELL_SOURCE_STATUS rcss ON CS.CELL_SOURCE_ID = RCSS.CELL_SOURCE_ID
 WHERE type IS NOT NULL
  AND CS.RECEIVED_DATE > to_date('03/01/2011', 'MM/DD/YYYY/')
  AND RCSS.STATUS like 'Term%'
GROUP BY BPI.TYPE, EXTRACT(MONTH FROM CS.RECEIVED_DATE)
ORDER BY month, type

This finds all cases that have been termed, easy enough. However, when I want to find the rate, I get a bit of a problem. I tried using a sub-query to catch the total amount of cases per type regardless of it's status, as such:

COUNT(*)/(SELECT COUNT(*) 
            FROM CELL_SOURCE cs_1 
            JOIN BASIC_PATHOLOGY_INFO bpi_1 ON CS_1.CELL_SOURCE_ID = BPI_1.CELL_SOURCE_ID
          WHERE BPI_1.TYPE = BPI.TYPE 
            AND EXTRACT(month from CS_1.RECEIVED_DATE) = EXTRACT(MONTH FROM CS.RECEIVED_DATE)) termed_cases

However, this throws an ORA-00979: not a GROUP BY expression error, and highlights BPI.TYPE from the sub-query.

Anyone have any idea what my error could actually be? Also, would an analytical function work better here than an aggregate function?


Solution

  • So, you need two counts: a total for all cases in the month and a total for just the Termed cases. The easiest way of doing this is to use a CASE() function to execute a conditional count, like this:

    SELECT BPI.TYPE,
           EXTRACT(MONTH FROM CS.RECEIVED_DATE) MONTH,
           COUNT(*) all_cases,
           sum(case when RCSS.STATUS like 'Term%' then 1 else 0 end ) termed_cases
      FROM CELL_SOURCE cs
      JOIN BASIC_PATHOLOGY_INFO bpi ON CS.CELL_SOURCE_ID = BPI.CELL_SOURCE_ID
      JOIN RECENT_CELL_SOURCE_STATUS rcss ON CS.CELL_SOURCE_ID = RCSS.CELL_SOURCE_ID
     WHERE tumor_type IS NOT NULL
      AND CS.RECEIVED_DATE > to_date('03/01/2011', 'MM/DD/YYYY/')
    GROUP BY BPI.TUMOR_TYPE, EXTRACT(MONTH FROM CS.RECEIVED_DATE)
    ORDER BY month, tumor_type
    

    Note that I have removed the LIKE filter from the WHERE clause.