oracle sql left join 和 count, sum, group by
oracle sql left join and count, sum, group by
我想计算每个问题的项目数量、金额和总百分比,仅限于给定的资助者和财政年度。出于某种原因,当我 运行 下面的查询时,我没有看到 null
来自左联接的值。
项目和问题的关系是一个问题可以有多个项目。问题 table 由目标 table 链接。
已更新
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
and o.fiscal_year = 2014
join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
questionId projectCount amount percentTotal
q1 14 54510 4
q2 29 1083598.72 76
q3 1 19900 1
q4 5 145631 10
q5 1 124999 9
q6 1 0 0
预期结果
questionId projectCount amount percentTotal
q1 14 54510 4
q2 29 1083598.72 76
q3 1 19900 1
q4 5 145631 10
q5 1 124999 9
q6 1 0 0
q7 <null> <null> <null>
一直向下使用左连接查询
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
left join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
and o.fiscal_year = 2014
left join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
结果
questionId projectCount amount percentTotal
na 51 1428638.72 11
q1 51 1428638.72 11
q2 51 1428638.72 11
q3 51 1428638.72 11
q4 51 1428638.72 11
q5 51 1428638.72 11
q6 51 1428638.72 11
q7 51 1428638.72 11
qother 51 1428638.72 11
一直向下进行左连接查询并调整 where 子句
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
left join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year and o.fiscal_year = 2014
left join funders f on p.funder_id = f.funder_id and f.funder_short_name ='foo'
where q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
结果
questionId projectCount amount percentTotal
na 1225 299628985.01 11
q1 1225 299628985.01 11
q2 1225 299628985.01 11
q3 1225 299628985.01 11
q4 1225 299628985.01 11
q5 1225 299628985.01 11
q6 1225 299628985.01 11
q7 1225 299628985.01 11
qother 1225 299628985.01 11
您遇到的问题与 sql 最不为人知的问题之一相关:关系的传递性。
您在项目和问题之间进行可选(外部)连接,但您要求在项目和目标(和资助者)之间建立强制(内部连接)关系:
计算中间结果集的传递系统使内连接占优势,这基本上意味着中间的外连接被忽略了。准确的说不是忽略,而是变成了inner join。
您得到的是内部联接一直向下的结果,而您实际上期望左联接按原样运行,并且 return 与任何项目无关的问题的空行。 ..但是引擎不是这样工作的,如上所述
在我的头脑中,我只是认为你可以一直使用左连接。但是您可能会遇到比预期更多的空行。这实际上取决于您对数据的处理方式。
另外,您的查询中似乎有一个应该修改的广泛连接。请试试这个:
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join objectives o on
o.sp_question_id = q.sp_question_id
and o.fiscal_year = 2014
left join projects p on o.fiscal_year = p.fiscal_year and o.sp_objective_id = p.sp_objective_id
left join funders f on p.funder_id = f.funder_id and f.funder_short_name ='foo'
where q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
我最终通过左连接两个子查询做了如下可怕的事情。如果有人有更好的方法,请post。
select t1.sp_question_id, t2.projectCount, t2.amount, t2.percentTotal
from (select
q.sp_question_id
from questions q
where q.fiscal_year = 2014) t1
left join
(select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id) t2
on t1.sp_question_id = t2.sp_question_id
我想计算每个问题的项目数量、金额和总百分比,仅限于给定的资助者和财政年度。出于某种原因,当我 运行 下面的查询时,我没有看到 null 来自左联接的值。
项目和问题的关系是一个问题可以有多个项目。问题 table 由目标 table 链接。
已更新
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
and o.fiscal_year = 2014
join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
questionId projectCount amount percentTotal
q1 14 54510 4
q2 29 1083598.72 76
q3 1 19900 1
q4 5 145631 10
q5 1 124999 9
q6 1 0 0
预期结果
questionId projectCount amount percentTotal
q1 14 54510 4
q2 29 1083598.72 76
q3 1 19900 1
q4 5 145631 10
q5 1 124999 9
q6 1 0 0
q7 <null> <null> <null>
一直向下使用左连接查询
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
left join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
and o.fiscal_year = 2014
left join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
结果
questionId projectCount amount percentTotal
na 51 1428638.72 11
q1 51 1428638.72 11
q2 51 1428638.72 11
q3 51 1428638.72 11
q4 51 1428638.72 11
q5 51 1428638.72 11
q6 51 1428638.72 11
q7 51 1428638.72 11
qother 51 1428638.72 11
一直向下进行左连接查询并调整 where 子句
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
left join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year and o.fiscal_year = 2014
left join funders f on p.funder_id = f.funder_id and f.funder_short_name ='foo'
where q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
结果
questionId projectCount amount percentTotal
na 1225 299628985.01 11
q1 1225 299628985.01 11
q2 1225 299628985.01 11
q3 1225 299628985.01 11
q4 1225 299628985.01 11
q5 1225 299628985.01 11
q6 1225 299628985.01 11
q7 1225 299628985.01 11
qother 1225 299628985.01 11
您遇到的问题与 sql 最不为人知的问题之一相关:关系的传递性。
您在项目和问题之间进行可选(外部)连接,但您要求在项目和目标(和资助者)之间建立强制(内部连接)关系:
计算中间结果集的传递系统使内连接占优势,这基本上意味着中间的外连接被忽略了。准确的说不是忽略,而是变成了inner join。
您得到的是内部联接一直向下的结果,而您实际上期望左联接按原样运行,并且 return 与任何项目无关的问题的空行。 ..但是引擎不是这样工作的,如上所述
在我的头脑中,我只是认为你可以一直使用左连接。但是您可能会遇到比预期更多的空行。这实际上取决于您对数据的处理方式。
另外,您的查询中似乎有一个应该修改的广泛连接。请试试这个:
select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join objectives o on
o.sp_question_id = q.sp_question_id
and o.fiscal_year = 2014
left join projects p on o.fiscal_year = p.fiscal_year and o.sp_objective_id = p.sp_objective_id
left join funders f on p.funder_id = f.funder_id and f.funder_short_name ='foo'
where q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id;
我最终通过左连接两个子查询做了如下可怕的事情。如果有人有更好的方法,请post。
select t1.sp_question_id, t2.projectCount, t2.amount, t2.percentTotal
from (select
q.sp_question_id
from questions q
where q.fiscal_year = 2014) t1
left join
(select
q.sp_question_id,
count(p.project_id) as projectCount,
sum(p.funding) as amount,
round(sum(p.funding)/sum(sum(p.funding)) over() *100) as percentTotal
from questions q
left join projects p on p.fiscal_year = q.fiscal_year
join objectives o on o.sp_objective_id = p.sp_objective_id
and o.sp_question_id = q.sp_question_id
and o.fiscal_year = p.fiscal_year
join funders f on p.funder_id = f.funder_id
where f.funder_short_name ='foo'
and q.fiscal_year = 2014
group by q.sp_question_id
order by q.sp_question_id) t2
on t1.sp_question_id = t2.sp_question_id