Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关系表的SQL查询_Sql - Fatal编程技术网

关系表的SQL查询

关系表的SQL查询,sql,Sql,员工可以在多个部门工作,每个部门可以有多个员工。因此需要一个关系表 表格: 环境管理计划(eid、ename、eage、esalary) 工作(eid、did、pct_时间) 部门(did、dname、预算、经理) 查找所有在软件和硬件领域工作的员工: SELECT e.ename FROM EMP e, Works w, Dept d WHERE e.eid = w.eid AND w.did = d.did AND d.did = (SELECT did FROM dept WHERE

员工可以在多个部门工作,每个部门可以有多个员工。因此需要一个关系表

表格:
环境管理计划(eid、ename、eage、esalary)
工作(eid、did、pct_时间)
部门(did、dname、预算、经理)

查找所有在软件和硬件领域工作的员工:

SELECT e.ename FROM EMP e, Works w, Dept d 
WHERE e.eid = w.eid AND w.did = d.did AND d.did = 
(SELECT did FROM dept WHERE dname = 'Hardware' OR 'Software')  
根据乔恩的说法:

SELECT e.ename FROM EMP e OR Works w OR Dept d 
WHERE e.eid = w.eid AND w.did = d.did AND d.did = 
(SELECT did FROM dept WHERE dname = 'Hardware' OR 'Software')

我只是不知道如何确保在同一个eid下,硬件和软件都有两个条目。

以下是解决此问题的步骤:

select e.name
  from emp e, works h_w, dept h_d, works s_w, dept s_d
 where e.eid = h_w.eid
   and e.eid = s_w.eid
   and h_w.did = h_d.did
   and h_d.dname = 'Hardware'
   and s_w.did = s_d.did
   and s_d.dname = 'Software'
  • 首先,获取
    works
    表中部门为硬件或软件的所有行
  • 然后,对于任何员工,如果存在两行,则意味着他/她同时为两个部门工作
  • 对于任何员工来说,如果少于两行,这意味着他/她只为其中一行工作,或者根本不工作
  • 我们需要检索正好有两行的员工
因此,我们首先可以从
works
表中进行选择,将其与
dept
表相关联,并筛选出非硬件或软件的任何部门:

SELECT a.*
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
然后我们要做的是按每个员工分组,这将允许我们访问聚合信息,例如每个员工的行数,或其他列的sum/max/min/avg/等。我们必须与伯爵合作:

SELECT a.eid
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
GROUP BY a.eid
HAVING COUNT(1) = 2
这只提供了正好有两行的
eid
s(即适用于软件和硬件部门)

但是,
eid
是不够的。我们需要有关员工的全部信息,因此必须将整个查询包装起来,并将其与employees表联接,以获取员工的其余信息:

SELECT a.*
FROM emp a
INNER JOIN 
(
    SELECT a.eid
    FROM works a
    INNER JOIN dept b ON a.did = b.did
    WHERE b.dname IN ('Hardware','Software')
    GROUP BY a.eid
    HAVING COUNT(1) = 2
) b ON a.eid = b.eid


这就是:在软件和硬件部门工作的员工。您可以单独执行上述每个查询,以查看我们如何得出最终解决方案的中间步骤。

以下是您如何解决问题的步骤:

  • 首先,获取
    works
    表中部门为硬件或软件的所有行
  • 然后,对于任何员工,如果存在两行,则意味着他/她同时为两个部门工作
  • 对于任何员工来说,如果少于两行,这意味着他/她只为其中一行工作,或者根本不工作
  • 我们需要检索正好有两行的员工
因此,我们首先可以从
works
表中进行选择,将其与
dept
表相关联,并筛选出非硬件或软件的任何部门:

SELECT a.*
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
然后我们要做的是按每个员工分组,这将允许我们访问聚合信息,例如每个员工的行数,或其他列的sum/max/min/avg/等。我们必须与伯爵合作:

SELECT a.eid
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
GROUP BY a.eid
HAVING COUNT(1) = 2
这只提供了正好有两行的
eid
s(即适用于软件和硬件部门)

但是,
eid
是不够的。我们需要有关员工的全部信息,因此必须将整个查询包装起来,并将其与employees表联接,以获取员工的其余信息:

SELECT a.*
FROM emp a
INNER JOIN 
(
    SELECT a.eid
    FROM works a
    INNER JOIN dept b ON a.did = b.did
    WHERE b.dname IN ('Hardware','Software')
    GROUP BY a.eid
    HAVING COUNT(1) = 2
) b ON a.eid = b.eid


这就是:在软件和硬件部门工作的员工。您可以单独执行上述每个查询,以查看我们如何得出最终解决方案的中间步骤。

以下是查询的替代公式:

SELECT e.*
  FROM emp AS e
  JOIN (SELECT w.eid
          FROM works AS w JOIN dept AS d
            ON d.did = w.did AND d.dname = 'Software') AS s
    ON s.eid = e.eid
  JOIN (SELECT w.eid
          FROM works AS w JOIN dept AS d
            ON d.did = w.did AND d.dname = 'Hardware') AS h
    ON h.eid = e.eid

这有两个对称的子查询,一个为软件部门生成员工ID,一个为硬件部门生成员工ID。所选员工的ID列在两个部门中(因为他们都是内部联接)。

以下是查询的另一种形式:

SELECT e.*
  FROM emp AS e
  JOIN (SELECT w.eid
          FROM works AS w JOIN dept AS d
            ON d.did = w.did AND d.dname = 'Software') AS s
    ON s.eid = e.eid
  JOIN (SELECT w.eid
          FROM works AS w JOIN dept AS d
            ON d.did = w.did AND d.dname = 'Hardware') AS h
    ON h.eid = e.eid

这有两个对称的子查询,一个为软件部门生成员工ID,一个为硬件部门生成员工ID。所选员工的ID列在两个部门中(因为他们都是内部联接)。

哇,这是一个很好的信息,我不知道你可以用不同的名称为同一个表别名。一般来说,你应该使用“现代”(意味着1992年后)SQL标准联接符号,而不是“古代”(意味着1992年前)FROM子句中以逗号分隔的表名列表。@JonathanLeffler将其中一个标记作为“家庭作业”并不奇怪。许多学校仍然使用旧的联接语法教授SQL。哇,这是一个很好的信息,我不知道你可以用不同的名称给同一个表别名。一般来说,你应该使用“现代”(意味着1992年后)SQL标准联接符号,而不是“古代”(意味着1992年前)FROM子句中以逗号分隔的表名列表。@JonathanLeffler将其中一个标记作为“家庭作业”并不奇怪。许多学校仍然使用旧的连接语法教授SQL。现在我明白了,但我不认为我自己会想到这一点。虽然,随着我的研究进展,我可能需要一些技巧来解决其他问题。非常感谢。现在我明白了,但我不认为我自己会想到这个。虽然,随着我的研究进展,我可能需要一些技巧来解决其他问题。非常感谢。Emp e或Works w或Dept d的
语法是标准SQL符号的一项创新。我担心您正在使用的DBMS可能会对语法产生异议并拒绝您的SQL语句。Emp e或Works w或Dept d的
语法是标准SQL符号的一项创新。我担心您正在使用的DBMS可能会对语法产生异议,并拒绝您的SQL语句。别名s和h会为您提供SELECT查询结果的句柄吗?我发现这是最难理解的一个。AS s
有效地将它附加到的查询结果命名为
s
(好像它是一个表或视图),类似地,
AS h
及其