Stack Exchange
Show SQL case statement as different columns
Is it possible to have each WHEN in a case statement be output in its own column? I tried it but with no luck. The closest I have come to what I want is below.
I currently have a query as follows:
select BH.BATCH                 as batch_number, 
       BS.TBS_DESCRIPTION       as batch_description,
       BH.NUM_VOUCHERS          as "NUM_VOUCHERS(BATCH)",
       case when VS.TVS_CODE = 1 then count(*) else 0 end as in_stock,
       case when VS.TVS_CODE = 3 then count(*) else 0 end as terminate,
       case when VS.TVS_CODE = 5 then count(*) else 0 end as in_progress,
       case when VS.TVS_CODE = 6 then count(*) else 0 end as used,
       case when VS.TVS_CODE = 8 then count(*) else 0 end as deactivate
from BATCH_HIST   bh,
     BATCH_STATUS bs,
     VOUCH_HIST   vh,
     VOUCH_STATUS vs
where substr(BH.ALLOCAT_DATE, 1, 6) = 201207
and   to_char(BH.STATUS) = BS.TBS_CODE
and   BH.BATCH = VH.BATCH
and   to_char(VH.STATUS) = VS.TVS_CODE
group by BH.BATCH,
         BS.TBS_DESCRIPTION,
         BH.NUM_VOUCHERS,
         VS.TVS_CODE
order by 1,2,3;

This gives me the following output, with each STATUS as a different record:
BATCH_NUMBER  | BATCH_DESCRIPTION  | NUM_VOUCHERS(BATCH)  | IN_STOCK  | TERMINATE  | IN_PROGRESS  | USED  | DEACTIVATE
------------------------------------------------------------------------------------------------------------------------------
4413565       |  Allocate          |  100                 |  67       |  0         |  0           |  0    |  0
4413565       |  Allocate          |  100                 |  0        |  0         |  0           |  33   |  0
4413566       |  Allocate          |  100                 |  63       |  0         |  0           |  0    |  0
4413566       |  Allocate          |  100                 |  0        |  0         |  0           |  37   |  0

I want this grouped together, so that there is one record per BATCH_NUMBER:
BATCH_NUMBER  | BATCH_DESCRIPTION  | NUM_VOUCHERS(BATCH)  | IN_STOCK  | TERMINATE  | IN_PROGRESS  | USED  | DEACTIVATE
------------------------------------------------------------------------------------------------------------------------------
4413565       |  Allocate          |  100                 |  67       |  0         |  0           |  33   |  0
4413566       |  Allocate          |  100                 |  63       |  0         |  0           |  37   |  0


Expression, as you have written it, requires group by, but if you sum matches you can eliminate tvs_code from group by:
select BH.BATCH                 as batch_number, 
       BS.TBS_DESCRIPTION       as batch_description,
       BH.NUM_VOUCHERS          as "NUM_VOUCHERS(BATCH)",
       sum (case when VS.TVS_CODE = 1 then 1 else 0 end) as in_stock,
       sum (case when VS.TVS_CODE = 3 then 1 else 0 end) as terminate,
       sum (case when VS.TVS_CODE = 5 then 1 else 0 end) as in_progress,
       sum (case when VS.TVS_CODE = 6 then 1 else 0 end) as used,
       sum (case when VS.TVS_CODE = 8 then 1 else 0 end) as deactivate
from BATCH_HIST   bh,
     BATCH_STATUS bs,
     VOUCH_HIST   vh,
     VOUCH_STATUS vs
where substr(BH.ALLOCAT_DATE, 1, 6) = 201207
and   to_char(BH.STATUS) = BS.TBS_CODE
and   BH.BATCH = VH.BATCH
and   to_char(VH.STATUS) = VS.TVS_CODE
group by BH.BATCH,
         BS.TBS_DESCRIPTION,
         BH.NUM_VOUCHERS
order by 1,2,3;


This wraps your current query. Maybe this can help you.
SELECT  subQuery.BATCH_NUMBER,
        subQuery.BATCH_DESCRIPTION,
        subquery."NUM_VOUCHERS(BATCH)",
        MAX(subquery.in_stock) AS in_stock,
        MAX(subquery.terminate) AS terminate,
        MAX(subquery.in_progress) AS in_progress,
        MAX(subquery.used) AS used,
        MAX(subquery.deactivate) AS deactivate
FROM
(
    select BH.BATCH                 as batch_number, 
           BS.TBS_DESCRIPTION       as batch_description,
           BH.NUM_VOUCHERS          as "NUM_VOUCHERS(BATCH)",
           case when VS.TVS_CODE = 1 then count(*) else 0 end as in_stock,
           case when VS.TVS_CODE = 3 then count(*) else 0 end as terminate,
           case when VS.TVS_CODE = 5 then count(*) else 0 end as in_progress,
           case when VS.TVS_CODE = 6 then count(*) else 0 end as used,
           case when VS.TVS_CODE = 8 then count(*) else 0 end as deactivate
    from BATCH_HIST   bh,
         BATCH_STATUS bs,
         VOUCH_HIST   vh,
         VOUCH_STATUS vs
    where substr(BH.ALLOCAT_DATE, 1, 6) = 201207
    and   to_char(BH.STATUS) = BS.TBS_CODE
    and   BH.BATCH = VH.BATCH
    and   to_char(VH.STATUS) = VS.TVS_CODE
    group by BH.BATCH,
             BS.TBS_DESCRIPTION,
             BH.NUM_VOUCHERS,
             VS.TVS_CODE
) AS subQuery
GROUP BY subQuery.BATCH_NUMBER,
        subQuery.BATCH_DESCRIPTION,
        subquery."NUM_VOUCHERS(BATCH)"

