SUM使用3个表和OUTER连接

时间:2013-03-13 06:54:47

标签: oracle oracle11g

基于三个表之间的连接存在sum问题。在下面的示例中,Ref每月包含11个条目。错误是除error_count之外的所有列的聚合。除了item_count之外,Items是所有列的聚合。错误和项目之间的关键是id和month year。 Ref和Errors之间的关键是error_code和month_year。 Ref和Items之间的关键是month_year。

我希望在结果中看到一个条目,该条目建立在Ref中的每个原始条目上,即每个月每月11个条目。运行以下命令时,如果找不到Ref和Errors之间的匹配,则不会创建任何条目,但我希望total_error_count在这种情况下输出零,因为它还可以根据对项目的连接输出total_item_count中的实际总和。

id = 1时缺少10行而id = 2则缺少27行。请告知,谢谢大家。

SQL Fiddle

Oracle 11g R2架构设置

create table Ref(
  month_year varchar2(6),
  error_code number(2)
)
/

create table Errors(
  id number(18),
  month_year varchar2(6),
  error_code number(2),
  include_ind varchar2(1),
  exclude_ind varchar2(1),
  error_count number
  )
/

create table Items(
  id number(18),
  month_year varchar2(6),
  include_ind varchar2(1),
  exclude_ind varchar2(1),
  item_count number
  )
/
create table Result(
  id number(18),
  error_code number(2),
  partition varchar2(10),
  month_year varchar2(6),
  total_error_count number,
  total_item_count number,
  rate number,
  query_timestamp varchar2(19)
)
/
INSERT INTO ref(month_year,error_code) VALUES ('201212','11');
INSERT INTO ref(month_year,error_code) VALUES ('201212','12');
INSERT INTO ref(month_year,error_code) VALUES ('201212','13');
INSERT INTO ref(month_year,error_code) VALUES ('201212','14');
INSERT INTO ref(month_year,error_code) VALUES ('201212','16');
INSERT INTO ref(month_year,error_code) VALUES ('201212','17');
INSERT INTO ref(month_year,error_code) VALUES ('201212','3');
INSERT INTO ref(month_year,error_code) VALUES ('201212','4');
INSERT INTO ref(month_year,error_code) VALUES ('201212','5');
INSERT INTO ref(month_year,error_code) VALUES ('201212','6');
INSERT INTO ref(month_year,error_code) VALUES ('201212','8');
INSERT INTO ref(month_year,error_code) VALUES ('201301','11');
INSERT INTO ref(month_year,error_code) VALUES ('201301','12');
INSERT INTO ref(month_year,error_code) VALUES ('201301','13');
INSERT INTO ref(month_year,error_code) VALUES ('201301','14');
INSERT INTO ref(month_year,error_code) VALUES ('201301','16');
INSERT INTO ref(month_year,error_code) VALUES ('201301','17');
INSERT INTO ref(month_year,error_code) VALUES ('201301','3');
INSERT INTO ref(month_year,error_code) VALUES ('201301','4');
INSERT INTO ref(month_year,error_code) VALUES ('201301','5');
INSERT INTO ref(month_year,error_code) VALUES ('201301','6');
INSERT INTO ref(month_year,error_code) VALUES ('201301','8');
INSERT INTO ref(month_year,error_code) VALUES ('201302','11');
INSERT INTO ref(month_year,error_code) VALUES ('201302','12');
INSERT INTO ref(month_year,error_code) VALUES ('201302','13');
INSERT INTO ref(month_year,error_code) VALUES ('201302','14');
INSERT INTO ref(month_year,error_code) VALUES ('201302','16');
INSERT INTO ref(month_year,error_code) VALUES ('201302','17');
INSERT INTO ref(month_year,error_code) VALUES ('201302','3');
INSERT INTO ref(month_year,error_code) VALUES ('201302','4');
INSERT INTO ref(month_year,error_code) VALUES ('201302','5');
INSERT INTO ref(month_year,error_code) VALUES ('201302','6');
INSERT INTO ref(month_year,error_code) VALUES ('201302','8');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('1','201212','Y','N','30');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('1','201301','Y','N','30');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('1','201302','Y','N','30');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('2','201212','Y','N','30');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('2','201301','Y','N','30');
INSERT INTO items(id,month_year,include_ind,exclude_ind,item_count) VALUES ('2','201302','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','4','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','5','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','6','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','11','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','12','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','13','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201212','14','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','5','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','6','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','11','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','12','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','13','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201301','14','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','4','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','5','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','6','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','11','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','12','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','13','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('1','201302','14','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201212','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201212','6','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201301','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201301','6','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201302','3','Y','N','30');
INSERT INTO errors(id,month_year,error_code,include_ind,exclude_ind,error_count) VALUES ('2','201302','6','Y','N','30');

查询1

BEGIN

INSERT INTO result

  SELECT 
        errors.id,
        ref.error_code,
        to_char(sysdate,'YYYY-MM-DD'),
        ref.month_year,
        SUM(errors.error_count),
        SUM(items.item_count),
        SUM(errors.error_count) / SUM(items.item_count),
        to_char(sysdate,'YYYY-MM-DD HH24:MI:SS')
FROM    ref
        RIGHT OUTER JOIN errors
        ON REF.error_code = errors.error_code
        AND REF.month_year = errors.month_year
           RIGHT OUTER JOIN items
           ON items.id = errors.id
           AND items.month_year = errors.month_year
WHERE   errors.include_ind = 'Y'
AND     errors.exclude_ind = 'N'
GROUP   BY
        errors.id,
        ref.error_code,
        ref.month_year,
        sysdate;
END;

[结果] [2]

查询2

select  *
from    result
order   by id, error_code, month_year

[结果] [3]

| ID | ERROR_CODE |  PARTITION | MONTH_YEAR | TOTAL_ERROR_COUNT | TOTAL_ITEM_COUNT | RATE |     QUERY_TIMESTAMP |
-----------------------------------------------------------------------------------------------------------------
|  1 |          3 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          3 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          3 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          4 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          4 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          5 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          5 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          5 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          6 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          6 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |          6 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         11 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         11 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         11 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         12 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         12 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         12 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         13 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         13 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         13 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         14 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         14 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  1 |         14 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          3 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          3 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          3 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          6 | 2013-03-13 |     201212 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          6 | 2013-03-13 |     201301 |                30 |               30 |    1 | 2013-03-13 06:43:16 |
|  2 |          6 | 2013-03-13 |     201302 |                30 |               30 |    1 | 2013-03-13 06:43:16 |

1 个答案:

答案 0 :(得分:0)

您可以利用COALESCE(a,b)将a的空值替换为b。然后,使用外连接,您将有足够的行

SELECT it.ID,
    r.MONTH_YEAR,
    r.ERROR_CODE,
    COALESCE(SUM(ERROR_COUNT),0) "TOTAL ERRORS",
    SUM(ITEM_COUNT) "TOTAL ITEMS",
    COALESCE(SUM(ERROR_COUNT),0)/SUM(ITEM_COUNT) "RATE"
FROM ITEMS it
    JOIN REF r
        ON (it.MONTH_YEAR = r.MONTH_YEAR)
    LEFT OUTER JOIN ERRORS er
        ON (r.MONTH_YEAR = er.MONTH_YEAR
            AND er.ERROR_CODE = r.ERROR_CODE
            AND er.ID = it.ID)
GROUP BY it.ID, 
    r.MONTH_YEAR, 
    r.ERROR_CODE
ORDER BY it.ID,
    r.MONTH_YEAR,
    r.ERROR_CODE