2015-04-17 3 views
0

Я являюсь tyring для создания оператора case, который будет возвращать минимальное или максимальное поле даты в зависимости от случая.Оператор case oracle, который возвращает результаты группы (min/max)

Поскольку в этом случае есть групповые функции, я думаю, что мне нужно поместить часть или весь оператор в группу по разделу, но я получаю сообщение об ошибке «ORA-00934: функция группы здесь не допускается», когда я попробуйте поместить его в группу по разделам.

Я также пытаюсь присоединиться к другой таблице, основанной на одном и том же случае, и это тоже не работает.

Вот "оскорбительный" саз:

случай когда id.DISC_PGM_NUM в ('1', '2', '2', '24B', '2', '3'), то макс (cn.CN_DATE) еще мин (cn.CN_DATE) конец, как Open_dt,

Вот полный запрос:

SELECT DISTINCT 
     id.CUST_ID, 
     case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then 'Flex Bundle' 
      when id.UDAC_CODE = 'ELB1' then 'ELB1' 
      when id.UDAC_CODE = 'ELB2' then 'ELB2' 
      when id.UDAC_CODE in ('GAT2', 'GAT1W','START', 'STARTW') then 'Smart Start Bundle' 
        else 'Unknown' 
      end as ProgramName,   
     case 
      when CN.SIGN_TYPE = 'U' then ' 920' 
      else id.DIV_NUM end as Div, 
     case 
      when CN.SIGN_TYPE = 'U' then '0920' 
      else id.UNIT_NUM end as Unit,   
     case 
      when CN.SIGN_TYPE = 'U' then 9200 
      else id.SALES_REP_ID end as Rep_ID, 
     case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end as Open_dt,    
     extract(year from case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end) as Yr,  
     To_Number(to_char(case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end,'IW'), '99') as Wk, 
     sum(id.ITEM_NISD_AMT) as BundleNI 

    from 
     ICV.VZ_ITEM_DETAIL       id 
     join ICV.VZ_CUSTOMER     vc on (vc.CUSTOMER_ID = id.CUST_ID) 
     left outer join (
      select CUSTOMER_ID, PRODUCT_CODE, PRODUCT_ISSUE_NUM, min(CONTRACT_DATE) as CN_date, SIGN_TYPE 
      from VAST.CONTRACT      
      where 
      SIGN_TYPE not in ('U', 'M', '-', 'C', 'L') 
      group by CUSTOMER_ID, PRODUCT_CODE, PRODUCT_ISSUE_NUM, sign_type) cn 
     on (ID.CUST_ID = CN.CUSTOMER_ID and ID.DIR_NUM = CN.PRODUCT_CODE 
                     and id.DIR_ISSUE_NUM = cn.PRODUCT_ISSUE_NUM) 
      where 
     (id.UDAC_CODE in ('ELB1', 'ELB2', 'GAT2', 'GAT1W','START', 'STARTW') 
     or id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B')) 
     and id.DIV_NUM in (' C2', ' C3', ' C4', ' C6', ' N1', ' N2', ' 371', ' K3', ' K1', ' K2' , ' 275', ' 253', ' 368', ' 296') 
     and id.ITEM_ACTION_CODE in ('A', 'I') 
      and id.PAY_PERIOD_YR= '2015' 
     and vc.SOURCE_SYSTEM_CDE= 'V' 
     and id.HANDLED_PAY_PERIOD_YR is not null 
     and HANDLED_PAY_PERIOD_NUM >=6 

    group by 
     id.CUST_ID, 
     case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then 'Flex Bundle' 
      when id.UDAC_CODE = 'ELB1' then 'ELB1' 
      when id.UDAC_CODE = 'ELB2' then 'ELB2' 
      when id.UDAC_CODE in ('GAT2', 'GAT1W','START', 'STARTW') then 'Smart Start Bundle' 
      else 'Unknown' 
      end,   
     case 
      when CN.SIGN_TYPE = 'U' then ' 920' 
      else id.DIV_NUM end, 
     case 
      when CN.SIGN_TYPE = 'U' then '0920' 
      else id.UNIT_NUM end,   
     case 
      when CN.SIGN_TYPE = 'U' then 9200 
      else id.SALES_REP_ID end,  
      case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end,    
     extract(year from case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end),  
     To_Number(to_char(case 
      when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 
      else min(cn.CN_DATE) end,'IW'), '99') 

возможно ли это?

+0

Вам разрешают иметь их в своем сазе, и они не идут в вашем GROUP BY. Покажите полную структуру SQL и таблицы, если вы ожидаете хорошего ответа. –

ответ

0

Вы можете делать то, что хотите, с помощью однострочного подзапроса в THEN-части CASE. Для примера.

SELECT 
CASE 
WHEN id.DISC_PGM_NUM IN ('15B','20B','25B','24B','28B','33B') 
THEN 
(
SELECT MAX(cn.CN_DATE) FROM <table_name> cn 
) 
ELSE 
(
SELECT MAX(cn.CN_DATE) FROM <table_name> cn 
) 
END AS Open_dt 
FROM .... 

Надеюсь, вы получите решение.

+0

Спасибо, Маниш - Что я буду помещать в раздел «группа»? –

+0

@MarkJustice - Где вы хотите разместить раздел GROUP BY? Вы не можете поместить часть подзапроса в раздел THEN, потому что я уже упоминал, что это должен быть подстрочный ряд с одной строкой. – Manish

+0

Мне может потребоваться заключить весь запрос, поэтому я понимаю.Псевдоним таблицы был «CN», что я поставил в положение, когда со следующей ** левое внешнее соединение ( выберите customer_id, product_code, PRODUCT_ISSUE_NUM, мин (CONTRACT_DATE) в CN_date, SIGN_TYPE из VAST.CONTRACT где SIGN_TYPE не ('U', 'M', '-', 'C', 'L') группа по CUSTOMER_ID, PRODUCT_CODE, PRODUCT_ISSUE_NUM, sign_type) cn on (ID.CUST_ID = CN.CUSTOMER_ID и ID.DIR_NUM = CN. PRODUCT_CODE и id.DIR_ISSUE_NUM = cn.PRODUCT_ISSUE_NUM) ** –

0

Без проверки вашей схемы, с которой сложно полностью выписать свой большой запрос. Но что-то вроде этого не будет работать:

when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 

Это не работает, потому что DISC_PGM_NUM не группируются.

Теперь, если вы объединяете DISC_PGM_NUM, он может работать. Как это:

when max(id.DISC_PGM_NUM) in ('15B','20B','25B','24B','28B','33B') then max(cn.CN_DATE) 

Проблема в том, что максимальная (id.DISC_PGM_NUM) не даст вам значение, которое вы ищете. Если запись имеет значения «15B» и «40B», «40B» будет вашим максимальным, и поэтому он не будет вписываться в предложение IN. Один из способов - использовать DECODE или другой оператор CASE.

Например:

when max(case when id.DISC_PGM_NUM in ('15B','20B','25B','24B','28B','33B') then 1 else 0 end) = 1 then max(cn.CN_DATE) 

Это будет рассматривать все значения, которые вы хотите как 1 и другие, как 0, так что ваша максимальная оценивает должным образом.

Заканчивать эту SQLFiddle: http://sqlfiddle.com/#!4/a330e/10

Смежные вопросы