2013-03-13 80 views
2

基於三個表之間的連接求和。在下面的例子中,Ref每月包含11個條目。錯誤是除了error_count之外的所有列的聚合。項目是除item_count之外的所有列的聚合。錯誤和項目之間的關鍵是id和month year。 Ref和Errors之間的關鍵是error_code和month_year。參考和項目之間的關鍵是month_year。SUM使用3個表和OUTER連接

我希望在結果中看到一個條目,它建立在每個原始條目的參考文獻中,即每月month_year,每個ID有11個條目。運行下面的代碼時,如果沒有找到Ref和Errors之間的匹配項,則不會創建條目,但是我希望total_error_count在該情況下輸出零,因爲它也可以基於對Items的連接輸出total_item_count中的實際總和。

我有10行缺少id = 1和27缺少id = 2。請指教,謝謝大家。

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 | 

回答

0

你可以採取COALESCE(A,B)用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 
+0

啊,非常感謝,得到了預期的結果!我認爲REF和ITEMS組合的外部聯接也有所幫助。 http://sqlfiddle.com/#!4/ae412/41/0 – xanthian21 2013-03-13 17:20:25

+0

的確,外連接允許您獲取所有行,包括ERROR_COUNT爲空的行。 coalesce()在這裏只是爲了在最終的結果集中放置一個不錯的0而不是null(並且允許我也假設這種劃分) – 2013-03-13 17:28:08