汇总行和列

时间:2018-05-18 18:33:01

标签: sql oracle

我正在尝试对此代码的列和行求和。我还想在报告中添加缺少的字段,但我无法。第一张图片是现在的结果,第二张图片是我喜欢的。谢谢。

enter image description here

enter image description here

WITH PLAN_CODES AS
    (
    SELECT DISTINCT test.MBR_COV.MBR_ID
    ,TRUNC(MONTHS_BETWEEN(SYSDATE,test.MBR.BTH_DT)/12) AS AGE
    ,FLOOR(MONTHS_BETWEEN(TO_DATE('03/31/2018','MM/DD/YYYY'),test.MBR.BTH_DT)/12) AS AGE_ON_REPORTING_DATE
    ,CASE WHEN test.MBR_COV.PLN_VAR_ID LIKE 'TE%' THEN 'EAST'
          WHEN test.MBR_COV.PLN_VAR_ID LIKE 'TW%' THEN 'WEST'
          WHEN test.MBR_COV.PLN_VAR_ID LIKE 'TM%' THEN 'MIDDLE'
          ELSE 'N/A' END AS REGION
    ,CASE WHEN SUBSTR(test.MBR_COV.LGCY_BEN_PLN_ID,1,4) = 'TNC4' THEN 'GROUP 4'
          WHEN SUBSTR(test.MBR_COV.LGCY_BEN_PLN_ID,1,4) = 'TNC5' THEN 'GROUP 5'
          WHEN SUBSTR(test.MBR_COV.LGCY_BEN_PLN_ID,1,4) = 'TNC6' THEN 'GROUP 6'
          WHEN SUBSTR(test.MBR_COV.LGCY_BEN_PLN_ID,1,4) = 'TNC7' THEN 'GROUP 7'
          WHEN SUBSTR(test.MBR_COV.LGCY_BEN_PLN_ID,1,4) = 'TNC8' THEN 'GROUP 8' 
          ELSE 'N/A' END AS CHOICES_GROUP
    FROM test.MBR_COV
     INNER JOIN test.MBR ON test.MBR_COV.MBR_ID = test.MBR.MBR_ID
    )


    SELECT DISTINCT PLAN_CODES.CHOICES_GROUP
    ,NULL AS AGE_GROUP
    ,NULL AS EAST
    ,NULL AS WEST
    ,NULL AS MIDDLE
    FROM PLAN_CODES
    WHERE PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 16 AND 62
      AND PLAN_CODES.REGION IN ('EAST','MIDDLE','WEST')
      AND PLAN_CODES.CHOICES_GROUP IN ('GROUP 4','GROUP 5','GROUP 6','GROUP 7','GROUP 8')
    UNION 
    SELECT DISTINCT PLAN_CODES.CHOICES_GROUP
    ,CASE WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 16 AND 18 THEN 'WORKING_AGE_MEMBERS_16_18'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 19 AND 21 THEN 'WORKING_AGE_MEMBERS_19_21'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 22 AND 25 THEN 'WORKING_AGE_MEMBERS_22_25'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 26 AND 34 THEN 'WORKING_AGE_MEMBERS_26_34'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 35 AND 46 THEN 'WORKING_AGE_MEMBERS_35_46'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 47 AND 62 THEN 'WORKING_AGE_MEMBERS_47_62'  END AS AGE_GROUP 
    ,SUM(CASE WHEN PLAN_CODES.REGION = 'EAST' THEN 1 ELSE 0 END) AS EAST
    ,SUM(CASE WHEN PLAN_CODES.REGION = 'WEST' THEN 1 ELSE 0 END) AS WEST
    ,SUM(CASE WHEN PLAN_CODES.REGION = 'MIDDLE' THEN 1 ELSE 0 END) AS MIDDLE
    FROM PLAN_CODES
    WHERE PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 16 AND 62
      AND PLAN_CODES.REGION IN ('EAST','MIDDLE','WEST')
      AND PLAN_CODES.CHOICES_GROUP IN ('GROUP 4','GROUP 5','GROUP 6','GROUP 7','GROUP 8')
    GROUP BY PLAN_CODES.CHOICES_GROUP
    ,CASE WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 16 AND 18 THEN 'WORKING_AGE_MEMBERS_16_18'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 19 AND 21 THEN 'WORKING_AGE_MEMBERS_19_21'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 22 AND 25 THEN 'WORKING_AGE_MEMBERS_22_25'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 26 AND 34 THEN 'WORKING_AGE_MEMBERS_26_34'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 35 AND 46 THEN 'WORKING_AGE_MEMBERS_35_46'
          WHEN PLAN_CODES.AGE_ON_REPORTING_DATE BETWEEN 47 AND 62 THEN 'WORKING_AGE_MEMBERS_47_62'  END 

1 个答案:

答案 0 :(得分:0)

http://sqlfiddle.com/#!4/ce4143/31

你可以这样做

WITH INTER_RESULT AS 
  ( 
    SELECT * 
      FROM (SELECT Possible_Values.Choices_Group,
                   Possible_Values.Age_Group,
                   COALESCE(TEST_DATA.east,0) AS east,
                   COALESCE(TEST_DATA.west,0) AS west,
                   COALESCE(TEST_DATA.middle,0) AS middle,
                   COALESCE(TEST_DATA.east,0) +
                   COALESCE(TEST_DATA.west,0) +
                   COALESCE(TEST_DATA.middle,0) AS region_total
              FROM (SELECT Choices_Group,
                           Age_Group
                      FROM (SELECT DISTINCT Choices_Group AS Choices_Group
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) CG,
                           (SELECT DISTINCT AGE_GROUP AS AGE_GROUP
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) TD
                    ) Possible_Values
              LEFT
              JOIN TEST_DATA
                ON Possible_Values.Choices_Group = TEST_DATA.Choices_Group
               AND Possible_Values.Age_Group = TEST_DATA.Age_Group
        )
    ) 
  SELECT * 
    FROM (
         SELECT * 
           FROM INTER_RESULT
          UNION
         SELECT Choices_Group,
                MAX('Age Total') AS AGE_GROUP,
                SUM(east),
                SUM(west),
                SUM(middle),
                SUM(region_total)
           FROM INTER_RESULT
          GROUP
             BY choices_group
     ) TMP
  ORDER
    BY Choices_Group,
       CASE WHEN Age_Group = 'Age Total' THEN 'Z'
            ELSE Age_Group
        END;

......或者,这是ROLLUP功能派上用场的地方。

WITH INTER_RESULT AS 
  ( 
    SELECT * 
      FROM (SELECT Possible_Values.Choices_Group,
                   Possible_Values.Age_Group,
                   COALESCE(TEST_DATA.east,0) AS east,
                   COALESCE(TEST_DATA.west,0) AS west,
                   COALESCE(TEST_DATA.middle,0) AS middle,
                   COALESCE(TEST_DATA.east,0) +
                   COALESCE(TEST_DATA.west,0) +
                   COALESCE(TEST_DATA.middle,0) AS region_total
              FROM (SELECT Choices_Group,
                           Age_Group
                      FROM (SELECT DISTINCT Choices_Group AS Choices_Group
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) CG,
                           (SELECT DISTINCT AGE_GROUP AS AGE_GROUP
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) TD
                    ) Possible_Values
              LEFT
              JOIN TEST_DATA
                ON Possible_Values.Choices_Group = TEST_DATA.Choices_Group
               AND Possible_Values.Age_Group = TEST_DATA.Age_Group
        )
    ) 
  SELECT Choices_Group,
         COALESCE(Age_Group,'Age Total') AS Age_Group,
         East,
         West,
         Middle,
         Region_Total
    FROM (SELECT Choices_Group,
                 Age_Group,
                 SUM(East) AS East,
                 SUM(West) AS West,
                 SUM(Middle) AS Middle,
                 SUM(region_total) AS region_total
            FROM INTER_RESULT
           GROUP 
              BY ROLLUP(Choices_Group,
                 Age_Group)
         ) TMP
   WHERE Choices_Group IS NOT NULL;

编辑:百分比。不是很漂亮,但它会起作用。

WITH INTER_RESULT AS 
  ( 
    SELECT * 
      FROM (SELECT Possible_Values.Choices_Group,
                   Possible_Values.Age_Group,
                   COALESCE(TEST_DATA.east,0) AS east,
                   COALESCE(TEST_DATA.west,0) AS west,
                   COALESCE(TEST_DATA.middle,0) AS middle,
                   COALESCE(TEST_DATA.east,0) +
                   COALESCE(TEST_DATA.west,0) +
                   COALESCE(TEST_DATA.middle,0) AS region_total
              FROM (SELECT Choices_Group,
                           Age_Group
                      FROM (SELECT DISTINCT Choices_Group AS Choices_Group
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) CG,
                           (SELECT DISTINCT AGE_GROUP AS AGE_GROUP
                              FROM TEST_DATA
                             WHERE age_group IS NOT NULL
                           ) TD
                    ) Possible_Values
              LEFT
              JOIN TEST_DATA
                ON Possible_Values.Choices_Group = TEST_DATA.Choices_Group
               AND Possible_Values.Age_Group = TEST_DATA.Age_Group
        )
    ) 

  SELECT *
    FROM (
         SELECT * 
           FROM INTER_RESULT
          UNION
         SELECT Choices_Group,
                MAX('Percentage of Total') AS AGE_GROUP,
                SUM(east)/(SELECT SUM(east) FROM INTER_RESULT),
                SUM(west)/(SELECT SUM(west) FROM INTER_RESULT),
                SUM(middle)/(SELECT SUM(middle) FROM INTER_RESULT),
                SUM(region_total)/(SELECT SUM(region_total) FROM INTER_RESULT)
           FROM INTER_RESULT
          GROUP
             BY choices_group
     ) TMP
  ORDER
    BY Choices_Group,
       CASE WHEN Age_Group = 'Percentage of Total' THEN 'Z'
            ELSE Age_Group
        END