如何在WHERE中使用子查询正确加入条件?

时间:2014-10-29 10:36:17

标签: php mysql sql database join

目前我的架构如下所示:

CREATE TABLE IF NOT EXISTS `hours` (
  `Project_ID` varchar(10) NOT NULL,
  `Project_Name` varchar(50) NOT NULL,
  `Res_ID` varchar(40) NOT NULL,
  `Date` date NOT NULL,
  `Hours` int(10) NOT NULL,
)

CREATE TABLE IF NOT EXISTS `project_resources` (
  `Project_ID` varchar(10) NOT NULL,
  `Res_ID` varchar(40) NOT NULL
)

//A single project Id can be assosiated with many resource id's

CREATE TABLE IF NOT EXISTS `resources` (
  `Res_ID` varchar(40) NOT NULL,
  `Res_Name` varchar(50) NOT NULL,
  `Email` varchar(50) NOT NULL,
  `Phone_Number` bigint(12) NOT NULL,
  `Reporting_Manager` varchar(50) NOT NULL,
  `Role` varchar(50) NOT NULL,
  `Designation` varchar(50) NOT NULL,
  `Password` varchar(50) NOT NULL
)

这里我试图生成一个查询,以便以下面的格式显示数据

资源名称|总和(小时)。

我尝试执行以下查询

SELECT res_name,sum(hours) FROM hours h
INNER JOIN resources r ON h.res_id=r.res_id
  WHERE r.res_id = (SELECT res_id FROM `project_resources` WHERE project_id='someproject')

我知道这会返回子查询返回超过1行的错误。但我只是想知道如何才能使这个查询正确。

4 个答案:

答案 0 :(得分:1)

我认为这会对你有帮助

Select res_name,sum(hours) 
from hours h inner join resources r on h.res_id=r.res_id 
where r.res_id IN (
      SELECT res_id 
      FROM `project_resources` 
      WHERE project_id='someproject'
)

如果您的子查询返回超过1行

,您可以在where语句中使用'IN'子句

答案 1 :(得分:0)

您可以使用in

Select res_name,sum(hours) 
from hours h inner join
     resources r
     on h.res_id = r.res_id 
where r.res_id in (SELECT res_id 
                   FROM `project_resources` 
                   WHERE project_id = 'someproject'
                  );

但是,我可能会建议只做多个连接:

Select res_name,sum(hours) 
from hours h inner join
     resources r
     on h.res_id = r.res_id inner join
     project_resources pr
     on pr.res_id = r.res_id and pr.project_id = 'someproject'

当然,如果project_resources表中有重复项,则无法使用。

答案 2 :(得分:0)

您正在选择所有项目的总小时数及其在某些项目中使用的资源(也)。由于可以有多个与“某些项目”关联的资源,因此请使用IN来获取所有资源。然后......

  • 组(假设它是唯一的,否则使用res_id)来获取每个资源的结果记录
  • 从结果中删除res_name(因为当有多个时,您只会随机显示其中一个)
  • 生成包含GROUP_CONCAT所有资源名称的字符串

所以:

SELECT 
  res_name,
  sum(hours) 
FROM hours h
INNER JOIN resources r ON h.res_id=r.res_id
WHERE r.res_id IN 
(
  SELECT res_id 
  FROM `project_resources` 
  WHERE project_id='someproject'
)
GROUP BY res_id;

或者:

SELECT 
  GROUP_CONCAT(res_name) AS res_names,
  sum(hours) 
FROM hours h
INNER JOIN resources r ON h.res_id=r.res_id
WHERE r.res_id IN
(
  SELECT res_id 
  FROM `project_resources` 
  WHERE project_id='someproject'
);

答案 3 :(得分:0)

所以基本上,你想要展示两件事:

  1. 资源名称
  2. 资源的总工作小时数
  3. 条件是Res_ID位于project_resources表中且项目ID为'someproject'

    右?

    然后让我们将这个问题分成三个小部分:

    第1部分:

    要获取您应该编写的资源的名称:

    SELECT rs.Res_Name
    FROM resources rs
    

    请注意,rs是表格resources的别名。

    好吗?

    现在 Part - 2:

    要获得资源的总工作小时数,您应该写一下:

    SELECT SUM(Hours)
    FROM hours h
    

    基本上,h是表hours的别名。我想你明白了,对吧?

    最后,第3部分:

    您的Project_ID应为'someproject'

    此外,Res_ID应位于project_resources内。

    现在,让我们将所有部分加在一起。现在我们得到:

     SELECT r.Res_Name, SUM(Hours)
     FROM hours h
     INNER JOIN resources r ON h.Res_ID = r.Res_ID
     INNER JOIN project_resources pr ON r.Res_ID = pr.Res_ID
     WHERE pr.Project_ID = 'someproject'
    

    基本上,我们首先将hoursresources加入,因为Res_ID在两个表中都相同,我们也加入了表resources project_resources 1}}鉴于Res_ID在两个表中都相同,Project_ID hours'someproject'

    希望这会给你你想要的东西。你明白了,对吧?

    然而,请注意。我注意到您对表hours使用了相同的名称,而它的列Hours。虽然,这不会导致任何问题,因为名称的情况不同,但这不是一个好的做法。您应该为列选择一个不同的,有意义的名称,以避免混淆和任何不必要的出现。享受编码!!!