I have this Oracle db structure (something like forum, ok):
CREATE TABLE sections
(
section_id INTEGER NOT NULL ,
parent_section INTEGER NULL ,
section_name VARCHAR2(256) NOT NULL ,
section_desc VARCHAR2(1024) NULL
);
CREATE TABLE topics
(
topic_id INTEGER NOT NULL ,
topic_name VARCHAR2(256) NOT NULL ,
section_id INTEGER NOT NULL
);
CREATE TABLE messages
(
msg_id INTEGER NOT NULL ,
msg_text CLOB NOT NULL ,
topic_id INTEGER NULL ,
msg_date DATE NOT NULL ,
user INTEGER NOT NULL
);
As you can see, sections
have hierarchical structure (by parent_section
column).
I want to make two queries:
- Get topics count in section by section id, considering all child sections.
- Same with messages instead of topics.
Ok, I'm trying to write first query, but even it doesn't work (return wrong count without errors), I have no idea why:
SELECT si, t.TOPIC_ID, COUNT(*)
FROM (
SELECT s.SECTION_ID si
FROM SECTIONS s
START WITH SECTION_ID = :sectionId
CONNECT BY PRIOR SECTION_ID = PARENT_SECTION
)
LEFT JOIN TOPICS t ON t.SECTION_ID = si
GROUP BY t.TOPIC_ID, si
EDIT:
While I'm setting up SQL Fiddle, I got some solution.
Firstly, we should use INNER JOIN
instead of LEFT JOIN
, because we don't need records with null
topic_id
.
Secondly, query with COUNT()
was wrong, it just returns same records with additional column COUNT
with 1
value. Now I just use SUM(1)
:
SELECT SUM(1)
FROM (
SELECT s.SECTION_ID si
FROM SECTIONS s
START WITH SECTION_ID = :sectionId
CONNECT BY PRIOR SECTION_ID = PARENT_SECTION
)
INNER JOIN TOPICS t ON t.SECTION_ID = si
GROUP BY 1
But it still not ideal solution, if we pass section without topics as START WITH SECTION_ID =
argument, we will get nothing as answer. It requires additional check in program for prevent NullPointerException
.
Maybe someone know, how can we get 0
as answer in this case?
SQLFiddle: http://sqlfiddle.com/#!4/8c093/21