2014-10-14 3 views
0

есть таблица:Создание средних групп клиентом

  • CUSTOMERID
  • START
  • END
  • СУММА

Нужно иметь результат:

  • CUSTOMERI D
  • 30 ДНЕЙ AVG СУММА
  • 15 ДНЕЙ AVG СУММА
  • 5 ДНЕЙ AVG СУММА

Это мой запрос:

SELECT CUSTOMERID, 
    CASE 
     WHEN START_DT > (SYSDATE - 5) 
      AND END_DT > (SYSDATE - 5) 
      THEN AVG(AMOUNT) 
     ELSE 0 
     END AS FIVE, 
    CASE 
     WHEN (
       START_DT BETWEEN (SYSDATE - 5) 
        AND SYSDATE - 15 
       ) 
      AND (
       END_DT BETWEEN (SYSDATE - 5) 
        AND SYSDATE - 15 
       ) 
      THEN AVG(AMOUNT) 
     ELSE 0 
     END AS FIFTEEN, 
    CASE 
     WHEN (
       START_DT BETWEEN (SYSDATE - 15) 
        AND SYSDATE - 30 
       ) 
      AND (
       END_DT BETWEEN (SYSDATE - 15) 
        AND SYSDATE - 30 
       ) 
      THEN AVG(AMOUNT) 
     ELSE 0 
     END AS THIRTY 
FROM MY_TABLE 
WHERE 1 = 1 
    AND START_DT > (SYSDATE - 30) 
    AND AMOUNT > 0 
GROUP BY CUSTOMERID, 
    START_DT, 
    END_DT 

Похоже, я не делаю это правильно, потому что я получаю слишком много нулей, но их не должно быть, поскольку я фильтрую AMOUNT> 0; какие-либо предложения?

ответ

2

Вам нужно group by где-то в пути. Что-то вроде:

SELECT CUSTOMERID, 
     AVG(CASE WHEN START_DT > (SYSDATE - 5) AND END_DT > (SYSDATE - 5) 
       THEN AMOUNT 
      END) AS FIVE, 
     AVG(CASE WHEN START_DT BETWEEN (SYSDATE - 5) AND SYSDATE - 15 AND 
        END_DT BETWEEN (SYSDATE - 5) AND SYSDATE - 15 
       THEN AMOUNT 
      END) AS FIFTEEN, 
     AVG(CASE WHEN START_DT BETWEEN (SYSDATE - 15) AND SYSDATE - 30 AND 
        END_DT BETWEEN (SYSDATE - 15) AND SYSDATE - 30 
       THEN AMOUNT 
      END) AS THIRTY 
FROM MY_TABLE 
WHERE 1 = 1 AND START_DT > (SYSDATE - 30) 
GROUP BY CUSTOMERID; 

Обратите внимание, что case идет внутри avg(). И нет предложения else. AVG() игнорирует значения NULL, которые вы хотите в этом случае.

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