加入多个表格

时间:2015-07-21 10:33:48

标签: sql oracle

简单的问题,但我对查询感到困惑,我有三个表

第一张表:项目

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

第二个表:project_estimates

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

第三表:project_expenditure:

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-16的项目详情

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

此外,2015-16财年的表二和表三中还有其他条目,我只需要在2015-16中具有项目估算的project_id,但我希望即使没有输入项目,也要使用project_expenditure的列值。我尝试使用a.proj_id=b.proj_ida.proj_id=c.proj_id(+),但它没有给出预期的输出。还有其他任何东西可以放在范围内以获得结果。

6 个答案:

答案 0 :(得分:1)

是的,我无法测试这个atm,但我会做这样的事情:

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

答案 1 :(得分:1)

答案首先应该是INNER连接,因为您只需要2015-16中具有估计值的项目,然后是左边连接,因为如果条目不存在,则希望它由NULL填充:

echo '"foo foo"' | jq 'match("(foo)"; "g")'

答案 2 :(得分:0)

尝试使用LEFT JOIN,如下所示:

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

如果我理解正确,它将达到你的需要。

答案 3 :(得分:0)

我不确定为什么你没有得到预期的输出,除非因为你没有在ext.fy = exp.fy上加入连接?<\ n / p>

这对我有用:

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

答案 4 :(得分:0)

试试这个:

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行的头条新闻,但它会提供数据输出。

希望它有所帮助。

答案 5 :(得分:0)

SELECT est.proj_id, 
       est.Q1, est.Q2, est.Q3, est.Q4, 
       exp.Q1, exp.Q2, exp.Q3, exp.Q4
  FROM project_estimates AS est 
  LEFT JOIN project_expenditure AS exp 
    ON exp.proj_id = est.proj_id 
   AND est.fy = '2015-16'
 ORDER BY est.proj_id