I'm working on creating a report for the open source tool Validation Manager. I managed to pull out a report of all requirements covered after lots of work. I'm trying to make a report to list the ones not covered, but using not in gets the query into a never ending processing state.
Here's the DD diagram:
The involved tables are in the bottom right side of the diagram. Sample data can be obtained here. What would be the correct way to get uncovered requirements?
FYI: Uncovered requirements are those that doesn't have a related step and/or their children requirements are covered.
The main issue is that there are, in theory, infinite number of levels of requirement relationships and the SQL I have only works for 2 levels. Trying to figure out a way to look as deep as necessary.
As reference, see the query for the covered requirements below (which is the opposite of what I need):
select
c.covered, t.total
from
(SELECT DISTINCT
count(distinct unique_id) as covered
FROM
requirement
WHERE
requirement.id IN (select
requirement.id
from
`requirement` requirement
INNER JOIN `step_has_requirement` step_has_requirement ON requirement.`id` = step_has_requirement.`requirement_id`
INNER JOIN `step` step ON step_has_requirement.`step_id` = step.`id`
AND step.`test_case_id` = step_has_requirement.`step_test_case_id`
AND step.`test_case_test_id` = step_has_requirement.`step_test_case_test_id`
INNER JOIN `test_case` test_case ON step.`test_case_id` = test_case.`id`
AND test_case.`test_id` = step.`test_case_test_id`
INNER JOIN `test` test ON test_case.`test_id` = test.`id`
INNER JOIN `test_plan_has_test` test_plan_has_test ON test.`id` = test_plan_has_test.`test_id`
INNER JOIN `test_plan` test_plan ON test_plan_has_test.`test_plan_id` = test_plan.`id`
AND test_plan.`test_project_id` = test_plan_has_test.`test_plan_test_project_id`
INNER JOIN `test_project` test_project ON test_plan.`test_project_id` = test_project.`id`
INNER JOIN `requirement_status` requirement_status ON requirement.`requirement_status_id` = requirement_status.`id`
INNER JOIN `requirement_spec_node` requirement_spec_node ON requirement.`requirement_spec_node_id` = requirement_spec_node.`id`
AND requirement_spec_node.`requirement_spec_project_id` = requirement.`requirement_spec_node_requirement_spec_project_id`
AND requirement_spec_node.`requirement_spec_spec_level_id` = requirement.`requirement_spec_node_requirement_spec_spec_level_id`
AND requirement_spec_node.`requirement_spec_id` = requirement.`requirement_spec_node_requirement_spec_id`
INNER JOIN `requirement_spec` requirement_spec ON requirement_spec_node.`requirement_spec_id` = requirement_spec.`id`
AND requirement_spec.`project_id` = requirement_spec_node.`requirement_spec_project_id`
AND requirement_spec.`spec_level_id` = requirement_spec_node.`requirement_spec_spec_level_id`
INNER JOIN `project` project ON requirement_spec.`project_id` = project.`id`
WHERE
requirement_status.status = 'general.approved'
and (project.id = $P{target_project_id}
or project.parent_project_id = $P{target_project_id}))
or requirement.id IN (select parent_requirement_id from requirement_has_requirement where parent_requirement_id = requirement.id
and requirement_id in (select
requirement.id
from
`requirement` requirement
INNER JOIN `step_has_requirement` step_has_requirement ON requirement.`id` = step_has_requirement.`requirement_id`
INNER JOIN `step` step ON step_has_requirement.`step_id` = step.`id`
AND step.`test_case_id` = step_has_requirement.`step_test_case_id`
AND step.`test_case_test_id` = step_has_requirement.`step_test_case_test_id`
INNER JOIN `test_case` test_case ON step.`test_case_id` = test_case.`id`
AND test_case.`test_id` = step.`test_case_test_id`
INNER JOIN `test` test ON test_case.`test_id` = test.`id`
INNER JOIN `test_plan_has_test` test_plan_has_test ON test.`id` = test_plan_has_test.`test_id`
INNER JOIN `test_plan` test_plan ON test_plan_has_test.`test_plan_id` = test_plan.`id`
AND test_plan.`test_project_id` = test_plan_has_test.`test_plan_test_project_id`
INNER JOIN `test_project` test_project ON test_plan.`test_project_id` = test_project.`id`
INNER JOIN `requirement_status` requirement_status ON requirement.`requirement_status_id` = requirement_status.`id`
INNER JOIN `requirement_spec_node` requirement_spec_node ON requirement.`requirement_spec_node_id` = requirement_spec_node.`id`
AND requirement_spec_node.`requirement_spec_project_id` = requirement.`requirement_spec_node_requirement_spec_project_id`
AND requirement_spec_node.`requirement_spec_spec_level_id` = requirement.`requirement_spec_node_requirement_spec_spec_level_id`
AND requirement_spec_node.`requirement_spec_id` = requirement.`requirement_spec_node_requirement_spec_id`
INNER JOIN `requirement_spec` requirement_spec ON requirement_spec_node.`requirement_spec_id` = requirement_spec.`id`
AND requirement_spec.`project_id` = requirement_spec_node.`requirement_spec_project_id`
AND requirement_spec.`spec_level_id` = requirement_spec_node.`requirement_spec_spec_level_id`
INNER JOIN `project` project ON requirement_spec.`project_id` = project.`id`
WHERE
requirement_status.status = 'general.approved'
and (project.id = $P{target_project_id}
or project.parent_project_id = $P{target_project_id})))
order by unique_id) c,
(SELECT
count(distinct unique_id) AS total
FROM
`requirement_status` requirement_status
INNER JOIN `requirement` requirement ON requirement_status.`id` = requirement.`requirement_status_id`
INNER JOIN `requirement_spec_node` requirement_spec_node ON requirement.`requirement_spec_node_id` = requirement_spec_node.`id`
AND requirement_spec_node.`requirement_spec_id` = requirement.`requirement_spec_node_requirement_spec_id`
INNER JOIN `requirement_spec` requirement_spec ON requirement_spec_node.`requirement_spec_id` = requirement_spec.`id`
AND requirement_spec.`spec_level_id` = requirement_spec_node.`requirement_spec_spec_level_id`
AND requirement_spec.`project_id` = requirement_spec_node.`requirement_spec_project_id`
INNER JOIN `project` project ON requirement_spec.`project_id` = project.`id`
INNER JOIN `spec_level` spec_level ON requirement_spec.`spec_level_id` = spec_level.`id`
WHERE
requirement_status.status = 'general.approved'
and (project.id = $P{target_project_id}
or project.parent_project_id = $P{target_project_id})) t
Note: The SQL there is an example on how I managed to do the opposite, get the covered requirements. I would like to get the ones not covered. That SQl query is working properly.
What I am looking for is same for the parts which are not covered now(in the above)!