计算内部的分析函数

时间:2015-07-14 09:51:56

标签: sql-server oracle

我有一个返回记录的查询,如。

Name   Total_Case_Count   User_Case_Count   P_Count  Rej_Count  PPP_Count    Active_Count

 XYZ        20                  10            05           02       01        02

我正在使用以下查询。

     select row_number() over (order by result.USER_NAME asc) as row_index,
           row_number() over (order by result.USER_NAME asc) as SERIAL_NO,
           result.USER_NAME, 
           result.USER_ACCOUNT_ID,
           MAX(Total_Case_Count) AS Total_Case_Count,
           MAX(User_Case_COUNT) AS User_Case_COUNT,
           MAX(Pending_Case_Count) AS Pending_Case_Count,
           MAX(Rejected_Case_Count) AS Rejected_Case_Count,
           MAX(Pending_For_Payment_Case_Count) AS Pending_For_Payment_Case_Count,
           MAX(Active_Case_Count) AS Active_Case_Count

    FROM
    (  SELECT               
              UA.USER_ACCOUNT_ID,
              UA.FIRST_NAME AS USER_NAME,
              NVL(PUIA.PARENT_USER_ACCOUNT_ID,C.CREATED_BY) PID,
              COUNT(*) OVER () Total_Case_Count,
              COUNT(*) OVER (PARTITION BY UA.USER_ACCOUNT_ID) User_Case_COUNT,

               CASE 
                        WHEN C.CASE_STATUS_ID = 2 THEN COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Pending_Case_Count,
               CASE 
                        WHEN C.CASE_STATUS_ID = 4 THEN COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Rejected_Case_Count,

               CASE 
                        WHEN C.CASE_STATUS_ID = 6 THEN COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Pending_For_Payment_Case_Count,
               CASE 
                        WHEN C.CASE_STATUS_ID In (1,3,5,7,8,9) THEN  COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Active_Case_Count

      FROM CASE C 
            INNER JOIN CASE_STATUS CS ON CS.CASE_STATUS_ID = C.CASE_STATUS_ID
            INNER JOIN SSO.PARENT_USER_IN_APPLICATION PUIA ON PUIA.APPLICATION_ID=12 AND PUIA.USER_ACCOUNT_ID=c.created_by
            INNER JOIN SSO.USER_ACCOUNTS UA ON UA.USER_ACCOUNT_ID=C.CREATED_BY
            INNER JOIN CASE_PARTY CP ON cp.sso_user_id=nvl(PUIA.PARENT_USER_ACCOUNT_ID,PUIA.USER_ACCOUNT_ID)
            inner join sso.User_In_Types uit on uit.USER_ACCOUNT_ID = UA.USER_ACCOUNT_ID 
            inner join SSO.USER_TYPES  ut on UT.USER_TYPE_ID = UiT.USER_TYPE_ID AND UT.APPLICATION_ID=12

      where 
            UT.APPLICATION_ID = 12 and UT.USER_TYPE_ID = 2170 
            and UA.USER_ACCOUNT_ID = 2187150 
            and c.case_source not in (4)

    ) result 
            GROUP BY result.USER_NAME, result.USER_ACCOUNT_ID
            ORDER BY USER_NAME

请查看 Active_Case_Count 列。它并没有带来正在通过的状态计数(1,3,5,6,7,8,9)。它只返回任何单个案件状态的计数。

实际上此声明并未返回所有状态的计数

CASE 
    WHEN C.CASE_STATUS_ID In (1,3,5,7,8,9) THEN  COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Active_Case_Count

任何建议真的很感激。

2 个答案:

答案 0 :(得分:1)

尝试使用:

CASE 
     WHEN C.CASE_STATUS_ID In (1,3,5,7,8,9) THEN 1 ELSE 0 end as Active_Case_Count

而不是:

CASE 
     WHEN C.CASE_STATUS_ID In (1,3,5,7,8,9) THEN  COUNT(*) OVER (PARTITION BY C.CASE_STATUS_ID,UA.USER_ACCOUNT_ID) end as Active_Case_Count

SUM(Active_Case_Count) AS Active_Case_Count

相反:

MAX(Active_Case_Count) AS Active_Case_Count

这将计算您的状态记录总数(1,3,5,7,8,9)

答案 1 :(得分:1)

我认为您可以使用以下内容替换case when c.case_statis_id ... then count(*) over ...语句:

count(case when c.case_status_id = 2 then c.case_status_id end) over (partition by UA.USER_ACCOUNT_ID) Pending_Case_Count,
count(case when c.case_status_id = 4 then c.case_status_id end) over (partition by UA.USER_ACCOUNT_ID) Rejected_Case_Count,
count(case when c.case_status_id = 6 then c.case_status_id end) over (partition by UA.USER_ACCOUNT_ID) Pending_For_Payment_Case_Count,
count(case when c.case_status_id In (1,3,5,7,8,9) then c.case_status_id end) over (partition by UA.USER_ACCOUNT_ID) Active_Case_Count

它具有减少分析函数正在执行的passthrough数量的优势,因为您现在只有两个不同的over()子句,而不是三个。

但是,我认为你甚至不需要分析函数 - 你在外部查询中做了一个组,那么为什么不将这项工作作为其中的一部分呢? E.g:

select row_number() over (order by result.USER_NAME asc) as row_index,
       row_number() over (order by result.USER_NAME asc) as SERIAL_NO,
       result.USER_NAME, 
       result.USER_ACCOUNT_ID,
       MAX(Total_Case_Count) AS Total_Case_Count,
       COUNT(*) AS User_Case_COUNT,
       count(case when result.case_status_id = 2 then result.case_status_id end) AS Pending_Case_Count,
       count(case when result.case_status_id = 4 then result.case_status_id end) AS Rejected_Case_Count,
       count(case when result.case_status_id = 6 then result.case_status_id end) AS Pending_For_Payment_Case_Count,
       count(case when result.case_status_id In (1,3,5,7,8,9) then result.case_status_id end) AS Active_Case_Count
FROM
      ( SELECT               
                UA.USER_ACCOUNT_ID,
                UA.FIRST_NAME AS USER_NAME,
                NVL(PUIA.PARENT_USER_ACCOUNT_ID,C.CREATED_BY) PID,
                c.case_status_id,
                COUNT(*) OVER () Total_Case_Count
        FROM CASE C 
              INNER JOIN CASE_STATUS CS ON CS.CASE_STATUS_ID = C.CASE_STATUS_ID
              INNER JOIN SSO.PARENT_USER_IN_APPLICATION PUIA ON PUIA.APPLICATION_ID=12 AND PUIA.USER_ACCOUNT_ID=c.created_by
              INNER JOIN SSO.USER_ACCOUNTS UA ON UA.USER_ACCOUNT_ID=C.CREATED_BY
              INNER JOIN CASE_PARTY CP ON cp.sso_user_id=nvl(PUIA.PARENT_USER_ACCOUNT_ID,PUIA.USER_ACCOUNT_ID)
              inner join sso.User_In_Types uit on uit.USER_ACCOUNT_ID = UA.USER_ACCOUNT_ID 
              inner join SSO.USER_TYPES  ut on UT.USER_TYPE_ID = UiT.USER_TYPE_ID AND UT.APPLICATION_ID=12
        where 
              UT.APPLICATION_ID = 12 and UT.USER_TYPE_ID = 2170 
              and UA.USER_ACCOUNT_ID = 2187150 
              and c.case_source not in (4)
      ) result 
GROUP BY result.USER_NAME, result.USER_ACCOUNT_ID
ORDER BY USER_NAME;

(N.B。:我假设UA.USER_ACCOUNT_ID是主键,因此组中包含USER_NAME不会改变任何内容。)

ETA:未经测试,因为您没有提供任何样本数据供我们使用。