到目前爲止,我從你的回答中拿掉的一件事是,對於一個給定的事件,它的附件和它的評論之間沒有直接的關係。 如果我理解正確,您希望將事件視爲附件和註釋的簡單「容器」,並且您只需要列出每個附件和註釋。哪個 附件碰巧出現在同一行中,因爲特定註釋對您而言是偶然的。
測試數據:
SQL> CREATE TABLE inc (incidentid NUMBER, incname VARCHAR2(20));
Table created.
SQL> INSERT INTO inc VALUES (1,'incident 1');
1 row created.
SQL> INSERT INTO inc VALUES (2,'incident 2');
1 row created.
SQL> CREATE TABLE att (att_id NUMBER, incidentid NUMBER, attname VARCHAR2(20));
Table created.
SQL> INSERT INTO att VALUES (101, 1, 'attachment 1');
1 row created.
SQL> INSERT INTO att VALUES (102, 1, 'attachment 2');
1 row created.
SQL> INSERT INTO att VALUES (103, 1, 'attachment 3');
1 row created.
SQL> INSERT INTO att VALUES (104, 1, 'attachment 4');
1 row created.
SQL> INSERT INTO att VALUES (105, 1, 'attachment 5');
1 row created.
SQL> INSERT INTO att VALUES (110, 2, 'attachment A');
1 row created.
SQL> INSERT INTO att VALUES (111, 2, 'attachment B');
1 row created.
SQL> INSERT INTO att VALUES (112, 2, 'attachment C');
1 row created.
SQL> CREATE TABLE comments (comment_id NUMBER, incidentid NUMBER, commenttext VARCHAR2(20));
Table created.
SQL> INSERT INTO comments VALUES (201, 1, 'first comment');
1 row created.
SQL> INSERT INTO comments VALUES (202, 1, 'second comment');
1 row created.
SQL> INSERT INTO comments VALUES (203, 1, 'third comment');
1 row created.
擬議QUERY:
SQL> WITH a AS (
2 SELECT att.incidentid
3 , COUNT(att.att_id) rows_per_incident
4 FROM att
5 GROUP BY att.incidentid
6 UNION ALL
7 SELECT comments.incidentid
8 , COUNT(comments.comment_id) rows_per_incident
9 FROM comments
10 GROUP BY comments.incidentid
11 )
12 , b AS (
13 SELECT inc.incidentid
14 , inc.incname
15 , ROW_NUMBER()
16 OVER (PARTITION BY inc.incidentid ORDER BY NULL) row_num
17 FROM inc
18 , (SELECT ROWNUM multiplier FROM DUAL CONNECT BY LEVEL <= (SELECT MAX(rows_per_incident) FROM a))
19 )
20 , c AS (
21 SELECT att.att_id
22 , att.incidentid
23 , att.attname
24 , ROW_NUMBER()
25 OVER (PARTITION BY att.incidentid ORDER BY att.att_id) att_rn
26 FROM att
27 )
28 , d AS (
29 SELECT comments.comment_id
30 , comments.incidentid
31 , comments.commenttext
32 , ROW_NUMBER()
33 OVER (PARTITION BY comments.incidentid ORDER BY comments.comment_id) comm_rn
34 FROM comments
35 )
36 , e AS (
37 SELECT c.incidentid
38 , c.att_id
39 , c.attname
40 , c.att_rn rn
41 , d.comment_id
42 , d.commenttext
43 FROM c
44 , d
45 WHERE c.incidentid = d.incidentid (+)
46 AND c.att_rn = d.comm_rn (+)
47 UNION ALL
48 SELECT TO_NUMBER(NULL) incidentid
49 , TO_NUMBER(NULL) att_id
50 , NULL attname
51 , d.comm_rn rn
52 , d.comment_id
53 , d.commenttext
54 FROM d
55 WHERE NOT EXISTS (SELECT NULL
56 FROM c
57 WHERE c.incidentid = d.incidentid
58 AND c.att_rn = d.comm_rn)
59 )
60 , f AS (
61 SELECT b.incidentid
62 , b.incname
63 , b.row_num
64 , e.att_id
65 , e.attname
66 , e.comment_id
67 , e.commenttext
68 FROM b
69 LEFT OUTER JOIN e ON b.incidentid = e.incidentid
70 AND b.row_num = e.rn
71 )
72 SELECT f.incidentid
73 , f.incname
74 , f.att_id
75 , f.attname
76 , f.comment_id
77 , f.commenttext
78 FROM f
79 WHERE NOT (f.att_id IS NULL AND f.comment_id IS NULL)
80 ORDER BY f.incidentid
81 , f.row_num
82 ;
INCIDENTID INCNAME ATT_ID ATTNAME COMMENT_ID COMMENTTEXT
---------- -------------------- ---------- -------------------- ---------- --------------------
1 incident 1 101 attachment 1 201 first comment
1 incident 1 102 attachment 2 202 second comment
1 incident 1 103 attachment 3 203 third comment
1 incident 1 104 attachment 4
1 incident 1 105 attachment 5
2 incident 2 110 attachment A
2 incident 2 111 attachment B
2 incident 2 112 attachment C
8 rows selected.
SQL>
切:你的查詢缺少一對夫婦'on's – bernie 2012-03-11 23:48:40
@MikeRyan的:回覆:「有沒有明顯的理由爲什麼它會這樣做「:我認爲你必須誤解問題中的某些內容,因爲它描述的正是」JOIN「的正常行爲。 'att'和'comment'之間有笛卡兒積,因爲任何'ON'或'WHERE'子句都沒有限制它們之間的關係。 – ruakh 2012-03-12 00:02:32
6_2010/01/07有4個附件和7條評論,因此它返回28行,而實際上它應該不超過7行 – user1262986 2012-03-12 00:20:24