1

表“salary”的列是 att_month、emp_id(指向员工的 emp_id)、总计。
表“组织”列是 ID、IDParent、名称。
表“employee”的列是 emp_id、emp_name、dep_id(指向组织的 ID)。

目标是根据这三个表计算每个部门,每个月的汇总。我想知道是否有人可以提供 SQL 查询或优化我的?

我目前的查询如下:

   select * from (select yy.IDParent, xx.ID, name, sum(heji) total
       from (select CONNECT_BY_ROOT(ID) ID, heji
                  from (select aa.ID,
                           aa.IDParent,
                           aa.name,
                           nvl(sum(HJ), 0) as heji
                          from (select * from organization) aa,
                           (select att_month,
                                   b.dep_id,
                                   sum(total) as HJ
                              from salary a, employee b
                             where b.emp_id = a.emp_id
                               and to_char(att_month, 'yyyy-mm') =
                                   '2012-05'
                             group by att_month, b.dep_id) bb
                     where aa.ID = bb.dep_id(+)
                     group by aa.ID, aa.IDParent, aa.name)
                connect by prior ID = IDParent) xx,
               organization yy
         where xx.ID = yy.ID
         group by yy.IDParent, xx.ID, name)
    connect by prior ID = IDParent
     start with ID = '000';

但是,它太长了,需要优化。如何?

    CREATE TABLE "EMPLOYEE" 
       (    "ID" NUMBER(5,0), 
        "EMP_ID" VARCHAR2(5) NOT NULL ENABLE, 
        "PASSWORD" VARCHAR2(8) DEFAULT 1, 
        "EMP_NAME" VARCHAR2(30), 
        "DEP_ID" VARCHAR2(5), 
        "LEV" CHAR(1), 
        "SEX" CHAR(1), 
        "CATEGORY" VARCHAR2(20), 
        "EDU" VARCHAR2(8), 
        "BIRTHDAY" DATE, 
        "GN" DATE, 
        "RJ" DATE, 
        "PID" VARCHAR2(18), 
        "LTY" CHAR(1), 
        "GWMC" VARCHAR2(40), 
        "ZJ" VARCHAR2(20), 
        "JSZW" VARCHAR2(20), 
        "JSJB" VARCHAR2(20), 
        "GWGZ" NUMBER(6,2), 
        "MEMO" VARCHAR2(40), 
        "MODILEV" NUMBER(*,0) DEFAULT 0, 
        "STATION" NUMBER(5,0), 
         CONSTRAINT "PK_EMPLOYEE" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE, 
         CONSTRAINT "UK_EMPLOYEE" UNIQUE ("EMP_ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 196608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP" ;

      CREATE UNIQUE INDEX "PK_EMPLOYEE" ON "EMPLOYEE" ("ID") 
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX" ;

      CREATE UNIQUE INDEX "UK_EMPLOYEE" ON "EMPLOYEE" ("EMP_ID") 
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX" ;

      ALTER TABLE "EMPLOYEE" ADD CONSTRAINT "PK_EMPLOYEE" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE;

      ALTER TABLE "EMPLOYEE" MODIFY ("EMP_ID" NOT NULL ENABLE);

      ALTER TABLE "EMPLOYEE" ADD CONSTRAINT "UK_EMPLOYEE" UNIQUE ("EMP_ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE;


      CREATE TABLE "SALARY" 
       (    "EMP_ID" VARCHAR2(5), 
        "ATT_MONTH" DATE, 
        "JXGZ" NUMBER(8,2), 
        "YCXJJ" NUMBER(8,2), 
        "BZZJT" NUMBER(8,2), 
        "YBJT" NUMBER(8,2), 
        "WQJT" NUMBER(8,2), 
        "JBGZ" NUMBER(8,2), 
        "QTJ" NUMBER(8,2), 
        "BF" NUMBER(8,2), 
        "GSKH" NUMBER(8,2), 
        "BMKH" NUMBER(8,2), 
        "TOTAL" NUMBER(8,2), 
        "MEMO" VARCHAR2(80), 
        "CHECKLOCK" VARCHAR2(1) DEFAULT '2', 
        "MODILOCK" NUMBER(*,0) DEFAULT 1, 
        "MODITIME" DATE, 
        "SGSFF" VARCHAR2(1) DEFAULT 0, 
        "CT" NUMBER(8,2), 
        "RCJB" NUMBER(8,2), 
        "XJFF" NUMBER(8,2), 
        "STATION" NUMBER(11,0), 
        "DEP_ID" VARCHAR2(5), 
        "ID" NUMBER(11,0), 
         CONSTRAINT "PK_SALARY" PRIMARY KEY ("EMP_ID", "ATT_MONTH")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 196608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 327680 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP" ;

      CREATE UNIQUE INDEX "PK_SALARY" ON "SALARY" ("EMP_ID", "ATT_MONTH") 
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 196608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX" ;

      ALTER TABLE "SALARY" ADD CONSTRAINT "PK_SALARY" PRIMARY KEY ("EMP_ID", "ATT_MONTH")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 196608 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE;


      CREATE TABLE "organization" 
       (    "IDParent" VARCHAR2(5) NOT NULL ENABLE, 
        "ID" VARCHAR2(5) NOT NULL ENABLE, 
        "ZJMC" VARCHAR2(60), 
        "ZJJS" VARCHAR2(50), 
         CONSTRAINT "PK_organization" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP" ;

      CREATE UNIQUE INDEX "PK_organization" ON "organization" ("ID") 
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX" ;

      ALTER TABLE "organization" ADD CONSTRAINT "PK_organization" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
      STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "JXKP_INDEX"  ENABLE;

      ALTER TABLE "organization" MODIFY ("IDParent" NOT NULL ENABLE);

      ALTER TABLE "organization" MODIFY ("ID" NOT NULL ENABLE);
4

2 回答 2

0

我试图简化您的查询,请看一下:

SELECT 
    yy.IDParent, 
    xx.ROOT_ID, 
    yy.name, 
    SUM(xx.heji) total
FROM (
    SELECT 
        CONNECT_BY_ROOT(t.ID) ROOT_ID,
        t.heji
    FROM    (
                SELECT 
                    dept.ID,
                    dept.IDParent,
                    dept.name,
                    NVL(bb.HJ, 0) as heji
                FROM organization dept LEFT OUTER JOIN
                         (SELECT 
                                att_month,
                                b.dep_id,
                                SUM(total) as HJ
                          FROM 
                                salary a INNER JOIN employee b ON b.emp_id = a.emp_id
                          WHERE 
                                TO_CHAR(att_month, 'yyyy-mm') = '2012-05'
                          GROUP BY 
                                att_month, 
                                b.dep_id
                         ) bb ON dept.ID = bb.dep_id
            ) t
     CONNECT BY PRIOR t.ID = t.IDParent
    ) xx INNER JOIN organization yy ON xx.ROOT_ID = yy.ID
GROUP BY 
    yy.IDParent, 
    xx.ROOT_ID, 
    yy.name;
于 2012-06-05T13:14:20.643 回答
0
  • 在组织上添加索引:(IDParent),使用计算统计
  • 添加基于函数的工资索引:TO_CHAR(att_month, 'yyyy-mm')

同样,由于您正在广泛解析一堆表,所以不要忘记检查您的全局统计信息是从何时生成的。如果您决定再次生成它们,则无需在创建密钥时使用 COMPUTE STATISTICS。

rgds。

于 2012-06-06T02:53:34.720 回答