联接查询以选择表

时间:2019-04-25 15:18:13

标签: sql oracle

我刚刚开始学习Join in SQL。我已经阅读了各种在线和离线教程以了解它。然后我开始做一些问题,以了解我的理解。 下表是

开发人员表
1)ID NUMBER
2)NAME VARCHAR2

客户表
1)编号NUMBER
2)NAME VARCHAR2

项目表
1)编号NUMBER
2)CUSTOMER_ID NUMBER(内部项目为NULL)
3)NAME VARCHAR2 4)TYPE NUMBER(0-Scrum,1-固定价格,2-概念证明)
5)START_DATE DATE(如果尚未开始,则为NULL)
6)END_DATE DATE(如果尚未完成,则为NULL)

任务表
1)ID号
2)NAME VARCHAR2
3)PROJECT_ID NUMBER
4)TYPE NUMBER(0-部署,1-支持,2-工单,3 –任务)
5)START_DATE DATE(如果尚未开始,则为NULL)
6)END_DATE DATE(如果尚未完成,则为NULL)

  Developer_Task表
1)DEV_ID NUMBER
2)TASK_ID NUMBER


现在,我想为这些问题写查询:

1)哪个开发人员花了时间在一个实际上已经完成的项目上,并且是为哪个客户服务的?
2)去年,每个开发人员为概念验证项目完成了多少支持任务?
3)哪个开发人员尚未参与Scrum项目?

联接需要一些公共属性。基于此,我们需要编写查询。我无法理解这些表之间的关系以及如何为这些表编写查询?

3 个答案:

答案 0 :(得分:0)

如果您想知道这些问题,首先需要在 Project表中添加Developer外键。
然后,您将能够在Project表中了解Developer的操作。
问候

答案 1 :(得分:0)

类似的东西:

1)

SELECT * FROM Developer D WHERE D.ID IN(
   SELECT DEV_ID FROM Developer_TASK DT 
   JOIN Tasks T ON DT.TASK_ID = T.ID 
   JOIN Project P ON P.ID = T.PROJECT_ID
   WHERE P.END_DATE > T.END_DATE
)

“检查当前日期时间”已经结束的项目

SELECT * FROM Developer D WHERE D.ID IN(
   SELECT DEV_ID FROM Developer_TASK DT 
   JOIN Tasks T ON DT.TASK_ID = T.ID 
   JOIN Project P ON P.ID = T.PROJECT_ID
   WHERE P.END_DATE < GETDATE()
)

2)

SELECT DEV_ID, Name, COUNT(*) AS Entries FROM Developer D 
    JOIN Developer_Task DT ON D.ID = DT.DEV_ID 
    JOIN Tasks T ON TD.Task_ID = T.ID 
    GROUP BY DEV_ID, YEAR(T.START_DATE), Name

3)

SELECT * FROM Developer 
          WHERE DEV_ID NOT IN(SELECT DEV_ID FROM Developer_TASK DT 
                JOIN Tasks T ON DT.TASK_ID = T.ID 
                JOIN Project P ON P.ID = T.PROJECT_ID)

答案 2 :(得分:0)

  

哪个开发人员花了时间在一个实际上已经完成的项目上,并且是为哪个客户服务的?

select p.id project_id, p.name project_name, d.name dev_name, 
       case p.customer_id when 0 then 'Internal' else c.name end cust_name
  from project p
    left join customer c on c.id = p.customer_id
    join task t on t.project_id = p.id
    join developer_task dt on dt.task_id = t.id
    join developer d on d.id = dt.dev_id
  where p.end_date is not null

这些是基本联接。 p.end_date is not null负责过滤完成的项目。我不知道customer表是否包含内部项目行,因此我使用case构造和left join不会丢失此类项目的行。

  

每个开发人员去年为概念验证项目完成了多少支持任务?

select id, name, nvl(cnt, 0) cnt
  from developer d
  left join (
    select dev_id, count(1) cnt
      from project p
        join task t on t.project_id = p.id
        join developer_task dt on dt.task_id = t.id
      where p.type = 2 
        and t.start_date <= trunc(sysdate, 'year') - 1 
        and (add_months(trunc(sysdate, 'year'), -12) <= t.end_date or t.end_date is null)
      group by dev_id) t on t.dev_id = d.id

在这里,我按任务的最初数量进行分组,以为每个开发人员进行概念验证项目。日期过滤有些棘手,请仔细研究。最后一步是显示所有开发人员的数据,因此即使他们没有参与这些项目,我也使用left join来显示所有数据。他们的计数= 0。

  

哪个开发人员尚未参与Scrum项目?

select * 
  from developer 
  where id not in (
    select dev_id 
      from project p 
      join task t on t.project_id = p.id 
      join developer_task dt on dt.task_id = t.id
      where p.type = 0)

找到所有Scrum项目的dev_id。然后使用not in。您也可以使用not existsminus和分析型count。 Oracle通常允许以多种方式执行任务。


这里是dbfiddle demo,其中包含所有有效的查询和示例数据,我想可以用来检查语法是否正确以及结果是否正常。