Sql 连接多个表
这个问题很简单,但我对这个查询感到困惑,我有三个表 第一表:项目Sql 连接多个表,sql,oracle,Sql,Oracle,这个问题很简单,但我对这个查询感到困惑,我有三个表 第一表:项目 proj_id project_cost project_description ------- ------------ ------------------- 1 123.45 construction plan A 2 222.22 construction plan B 3 3
proj_id project_cost project_description
------- ------------ -------------------
1 123.45 construction plan A
2 222.22 construction plan B
3 333.33 construction plan c
4 444.44 construction plan D
5 555.55 construction plan E
第二表:项目估算
est_id proj_id fy Q1 Q2 Q3 Q4
------- ------- --------- ----- ------ ----- -------
1 2 2015-16 12 11 15 19
2 3 2015-16 11 22 45 23
3 4 2015-16 31 32 36 56
4 1 2015-16 51 34 45 78
5 5 2015-16 33 44 59 98
第三表:项目支出:
exp_id proj_id fy Q1 Q2 Q3 Q4
------- ------- --------- ----- ------ ----- -------
1 3 2015-16 10 12 41 15
2 5 2015-16 31 24 39 70
现在我想连接这些表以获得如下输出:
2015-2016年项目详情
proj_id Proposed expenditure
--------- ----------------------- ---------------------
Q1 Q2 Q3 Q4 Q1 Q2 Q3 Q4
----------------------------------------------------------------
1 51 34 45 78 NULL NULL NULL NULL
2 12 11 15 19 NULL NULL NULL NULL
3 11 22 45 23 10 12 41 15
4 31 32 36 56 NULL NULL NULL NULL
5 33 44 59 98 31 24 39 70
此外,表2和表3中还有2015-16年财务报表的其他条目,我只需要项目编号,其中包含2015-16年的项目估算,但我需要项目支出中的列值,即使没有条目。我尝试了
a.proj_id=b.proj_id
和a.proj_id=c.proj_id(+)
,但没有给出预期的输出。可以放入范围内以获得结果的任何其他内容。尝试使用左连接,如下所示:
SELECT projects.proj_id,
project_estimates.Q1,
project_estimates.Q2,
project_estimates.Q3,
project_estimates.Q4,
project_expenditure.Q1,
project_expenditure.Q2,
project_expenditure.Q3,
project_expenditure.Q4
FROM projects
LEFT JOIN project_estimates ON (project_estimates.proj_id = projects.proj_id)
LEFT JOIN project_expenditure ON (project_expenditure.proj_id = projects.proj_id)
ORDER BY projects.proj_id
SELECT
proj_id,
project_estimates.Q1,
project_estimates.Q2,
project_estimates.Q3,
project_estimates.Q4,
project_expenditure.Q1,
project_expenditure.Q2,
project_expenditure.Q3,
project_expenditure.Q4
FROM projects
LEFT JOIN project_estimates ON (project_estimates.proj_id = projects.proj_id)
LEFT JOIN project_expenditure ON (project_expenditure.proj_id = projects.proj_id)
WHERE projects.proj_id IN (
(SELECT proj_id FROM project_estimates WHERE (project_estimates.fy = '2015-16'))
UNION
(SELECT proj_id FROM project_expenditure WHERE (project_expenditure.fy = '2015-16'))
GROUP BY proj_id
)
ORDER BY proj_id
如果我理解正确,它将满足您的需要。我不确定您为什么没有获得预期的输出,除非是因为您没有在ext.fy=exp.fy上加入连接 这对我很有用:
with projects as (select 1 proj_id, 123.45 project_cost, 'construction plan A' project_description from dual union all
select 2 proj_id, 222.22 project_cost, 'construction plan B' project_description from dual union all
select 3 proj_id, 333.33 project_cost, 'construction plan C' project_description from dual union all
select 4 proj_id, 444.44 project_cost, 'construction plan D' project_description from dual union all
select 5 proj_id, 555.55 project_cost, 'construction plan E' project_description from dual),
project_estimates as (select 1 est_id, 2 proj_id, '2015-16' fy, 12 q1, 11 q2, 15 q3, 19 q4 from dual union all
select 2 est_id, 3 proj_id, '2015-16' fy, 11 q1, 22 q2, 45 q3, 23 q4 from dual union all
select 3 est_id, 4 proj_id, '2015-16' fy, 31 q1, 32 q2, 36 q3, 59 q4 from dual union all
select 4 est_id, 1 proj_id, '2015-16' fy, 51 q1, 34 q2, 34 q3, 78 q4 from dual union all
select 5 est_id, 5 proj_id, '2015-16' fy, 33 q1, 44 q2, 44 q3, 98 q4 from dual union all
select 6 est_id, 1 proj_id, '2016-17' fy, 33 q1, 44 q2, 44 q3, 98 q4 from dual),
project_expenditures as (select 1 exp_id, 3 proj_id, '2015-16' fy, 10 q1, 12 q2, 41 q3, 15 q4 from dual union all
select 2 exp_id, 5 proj_id, '2015-16' fy, 31 q1, 24 q2, 39 q3, 70 q4 from dual)
--end of mimicking your tables; see the query below:
select est.fy,
prj.proj_id,
est.q1 proposed_q1,
est.q2 proposed_q2,
est.q3 proposed_q3,
est.q4 proposed_q4,
exp.q1 expenditure_q1,
exp.q2 expenditure_q2,
exp.q3 expenditure_q3,
exp.q4 expenditure_q4
from projects prj
left outer join project_estimates est on (prj.proj_id = est.proj_id)
left outer join project_expenditures exp on (prj.proj_id = exp.proj_id and est.fy = exp.fy)
order by fy, proj_id;
FY PROJ_ID PROPOSED_Q1 PROPOSED_Q2 PROPOSED_Q3 PROPOSED_Q4 EXPENDITURE_Q1 EXPENDITURE_Q2 EXPENDITURE_Q3 EXPENDITURE_Q4
------- ---------- ----------- ----------- ----------- ----------- -------------- -------------- -------------- --------------
2015-16 1 51 34 34 78
2015-16 2 12 11 15 19
2015-16 3 11 22 45 23 10 12 41 15
2015-16 4 31 32 36 59
2015-16 5 33 44 44 98 31 24 39 70
2016-17 1 33 44 44 98
如果你也可以有没有预算的支出,那么这应该可以做到:
with projects as (select 1 proj_id, 123.45 project_cost, 'construction plan A' project_description from dual union all
select 2 proj_id, 222.22 project_cost, 'construction plan B' project_description from dual union all
select 3 proj_id, 333.33 project_cost, 'construction plan C' project_description from dual union all
select 4 proj_id, 444.44 project_cost, 'construction plan D' project_description from dual union all
select 5 proj_id, 555.55 project_cost, 'construction plan E' project_description from dual),
project_estimates as (select 1 est_id, 2 proj_id, '2015-16' fy, 12 q1, 11 q2, 15 q3, 19 q4 from dual union all
select 2 est_id, 3 proj_id, '2015-16' fy, 11 q1, 22 q2, 45 q3, 23 q4 from dual union all
select 3 est_id, 4 proj_id, '2015-16' fy, 31 q1, 32 q2, 36 q3, 59 q4 from dual union all
select 4 est_id, 1 proj_id, '2015-16' fy, 51 q1, 34 q2, 34 q3, 78 q4 from dual union all
select 5 est_id, 5 proj_id, '2015-16' fy, 33 q1, 44 q2, 44 q3, 98 q4 from dual union all
select 6 est_id, 1 proj_id, '2016-17' fy, 33 q1, 44 q2, 44 q3, 98 q4 from dual),
project_expenditures as (select 1 exp_id, 3 proj_id, '2015-16' fy, 10 q1, 12 q2, 41 q3, 15 q4 from dual union all
select 2 exp_id, 5 proj_id, '2015-16' fy, 31 q1, 24 q2, 39 q3, 70 q4 from dual union all
select 3 exp_id, 4 proj_id, '2016-17' fy, 31 q1, 24 q2, 39 q3, 70 q4 from dual)
--end of mimicking your tables; see the query below:
select coalesce(exp.fy, est.fy) fy,
coalesce(exp.proj_id, est.proj_id, prj.proj_id) proj_id,
est.q1 proposed_q1,
est.q2 proposed_q2,
est.q3 proposed_q3,
est.q4 proposed_q4,
exp.q1 expenditure_q1,
exp.q2 expenditure_q2,
exp.q3 expenditure_q3,
exp.q4 expenditure_q4
from projects prj
left outer join project_estimates est on (prj.proj_id = est.proj_id)
full outer join project_expenditures exp on (prj.proj_id = exp.proj_id and est.fy = exp.fy)
order by fy, proj_id;
FY PROJ_ID PROPOSED_Q1 PROPOSED_Q2 PROPOSED_Q3 PROPOSED_Q4 EXPENDITURE_Q1 EXPENDITURE_Q2 EXPENDITURE_Q3 EXPENDITURE_Q4
------- ---------- ----------- ----------- ----------- ----------- -------------- -------------- -------------- --------------
2015-16 1 51 34 34 78
2015-16 2 12 11 15 19
2015-16 3 11 22 45 23 10 12 41 15
2015-16 4 31 32 36 59
2015-16 5 33 44 44 98 31 24 39 70
2016-17 1 33 44 44 98
2016-17 4 31 24 39 70
试试这个:
SELECT p.proj_id, pes.Q1, pes.Q2, pes.Q3, pes.Q4, pe.Q1, pe.Q2, pe.Q3, pe.Q4
FROM projects AS p
JOIN project_estimates AS pes ON p.proj_id = pes.proj_id AND pes.fy = '2015-16'
LEFT JOIN project_expenditure AS pe ON p.proj_id = pe.proj_id AND pe.fy = '2015-16'
ORDER BY p.proj_id
这不会让您看到Q1-Q4行的标题,但会给出数据输出
希望能有帮助。对,我无法测试这个atm,但我会这样做:
SELECT projects.proj_id,
project_estimates.Q1,
project_estimates.Q2,
project_estimates.Q3,
project_estimates.Q4,
project_expenditure.Q1,
project_expenditure.Q2,
project_expenditure.Q3,
project_expenditure.Q4
FROM projects
LEFT JOIN project_estimates ON (project_estimates.proj_id = projects.proj_id)
LEFT JOIN project_expenditure ON (project_expenditure.proj_id = projects.proj_id)
ORDER BY projects.proj_id
SELECT
proj_id,
project_estimates.Q1,
project_estimates.Q2,
project_estimates.Q3,
project_estimates.Q4,
project_expenditure.Q1,
project_expenditure.Q2,
project_expenditure.Q3,
project_expenditure.Q4
FROM projects
LEFT JOIN project_estimates ON (project_estimates.proj_id = projects.proj_id)
LEFT JOIN project_expenditure ON (project_expenditure.proj_id = projects.proj_id)
WHERE projects.proj_id IN (
(SELECT proj_id FROM project_estimates WHERE (project_estimates.fy = '2015-16'))
UNION
(SELECT proj_id FROM project_expenditure WHERE (project_expenditure.fy = '2015-16'))
GROUP BY proj_id
)
ORDER BY proj_id
答案应该首先是一个内部联接,因为您只希望项目在2015-16年进行估算,然后是一个左联接,因为如果条目不存在,您希望它填充为NULL:
SELECT prj.proj_id,
prj_est.Q1,
prj_est.Q2,
prj_est.Q3,
prj_est.Q4,
prj_exp.Q1,
prj_exp.Q2,
prj_exp.Q3,
prj_exp.Q4
FROM projects AS prj
INNER JOIN project_estimates AS prj_est ON prj.proj_id = prj_est.proj_id
AND prj_est.fy = '2015-16'
LEFT JOIN project_expenditure AS prj_exp ON prj.proj_id = prj_exp.proj_id;
能否提供SQL语句及其执行结果?