按客户创建平均组

时间:2014-10-14 21:30:52

标签: sql oracle group-by aggregate

有一张桌子:

  • CUSTOMERID
  • START
  • END
  • 金额

需要有结果:

  • CUSTOMERID
  • 30天AVG AMOUNT
  • 15天AVG AMOUNT
  • 5天AVG AMOUNT

这是我的查询:

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过滤它们不应该在那里;有什么建议吗?

1 个答案:

答案 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个值,这就是您在这种情况下所需的值。

相关问题