Mysql 有人能给我解释一下这三个SQL查询吗?

Mysql 有人能给我解释一下这三个SQL查询吗?,mysql,database,database-design,Mysql,Database,Database Design,我是一个数据库类的学生,正在练习一些SQL问题,以提高我在书中的技能。以下是我用于参考问题的数据库模式(发布的解决方案是正确的,我只需要一些解释来更好地理解它们): Q1:检索与员工同名且性别相同的受抚养人的每位员工的姓名。 SELECT E.FNAME, E.LNAME FROM EMPLOYEE AS E WHERE E.SSN IN (SELECT D.ESSN, FROM DEPENDENT AS D, WHERE E.FNAME = D.DEPENDENT_NAME AND D.SE

我是一个数据库类的学生,正在练习一些SQL问题,以提高我在书中的技能。以下是我用于参考问题的数据库模式(发布的解决方案是正确的,我只需要一些解释来更好地理解它们):

Q1:检索与员工同名且性别相同的受抚养人的每位员工的姓名。

SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE E.SSN IN (SELECT D.ESSN, FROM DEPENDENT AS D, WHERE E.FNAME = D.DEPENDENT_NAME AND D.SEX = E.SEX);
SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE NOT EXISTS (SELECT *, FROM DEPENDENT AS D, WHERE D.ESSN = E.SSN);
我对这个问题有点困惑。第一个FROM子句不应该包括“DEPENDENT AS D”吗?我们为什么要在这里筑巢?我看不出有什么原因。这似乎让事情变得更复杂了

Q2:检索没有任何家属的员工的姓名。

SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE E.SSN IN (SELECT D.ESSN, FROM DEPENDENT AS D, WHERE E.FNAME = D.DEPENDENT_NAME AND D.SEX = E.SEX);
SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE NOT EXISTS (SELECT *, FROM DEPENDENT AS D, WHERE D.ESSN = E.SSN);
我们不能使用NULL而不是WHERE NOT EXISTS吗

为什么要使用“WHERE NOT EXISTS”子句?我们不能只使用NULL吗?

SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE E.SSN IN (SELECT D.ESSN, FROM DEPENDENT AS D, WHERE E.FNAME = D.DEPENDENT_NAME AND D.SEX = E.SEX);
SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE NOT EXISTS (SELECT *, FROM DEPENDENT AS D, WHERE D.ESSN = E.SSN);
问题3:列出至少有一名受抚养人的经理的姓名

SELECT FNAME, LNAME
FROM EMPLOYEE
WHERE EXISTS(SELECT * FROM DEPARTMENT WHERE SSN = MGR_SSN)
WHERE EXISTS (SELECT * FROM DEPENDENT WHERE ESSN = SSN);
老实说,我不明白这个问题背后的理由。我有点明白,但我甚至很难向自己解释。FROM子句不应该包括部门和从属吗?为什么只包括员工?如果有人能一步一步地引导我完成这个查询,并向我解释为什么我们使用WHERE-EXISTS子句,这将非常有帮助


需要有人教这门课如何正确使用逗号


问题1:不,您不希望第一个发件人位于
DEPENDENT
,您正在尝试选择员工信息,而不是dependents。子查询用于查找与父项具有相同姓名和性别的从属项的essn(父ssn)值

编辑:在进一步检查Q1查询时,它确实看起来相当复杂;而且几乎肯定不是获取这些信息的最佳方式。将子查询保持原样,使用EXISTS而不是IN是不够的,因为有可能存在一个与相关员工同名、性别相同的受抚养人,而该受抚养人实际上不是该员工的受抚养人。如果将
和D.ESSN=E.SSN
添加到子查询的WHERE条件中,那么EXISTS将是一个有效的选择。但是,如果子查询不能完全清楚地表明在所涉及的三个字段上进行内部联接是一个更好的选择,那么就没有办法“取消关联”子查询(少数情况下,一些傻子会在自己的名字后面加上一个以上相同性别的受抚养人;在这种情况下,内部连接可能仍然是更好的解决方案,但现在应该在SELECT中使用DISTINCE。)


问题2:我不确定您打算如何使用NULL


问题3:同样,您不会(或至少不需要)从外部查询中的其他表中进行选择,因为您在结果中不需要这些表中的数据。这两个
存在的
条件(可能)使用相关子查询(可能效率/性能较差,联接通常快得多);也许用这样的别名写会更明显:

SELECT e.FNAME, e,LNAME
FROM EMPLOYEE AS e
WHERE EXISTS(SELECT * FROM DEPARTMENT AS d WHERE e.SSN = d.MGR_SSN)
   AND EXISTS (SELECT * FROM DEPENDENT AS d WHERE d.ESSN = e.SSN);
SELECT DISTINCT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
JOIN DEPENDENT D
  ON E.SSN = D.ESSN
 AND E.FNAME = D.DEPENDENT_NAME 
 AND D.SEX = E.SEX
(编辑:正如另一位回答者所指出的,一个查询中不能有多个WHERE(同一“级别”)

或者把它翻译成英语

“请告诉我员工的名字和姓氏 经理的ssn与员工的ssn相同的部门,以及 存在一个从属项,其父项的ssn与 员工的。”


第一个无法运行。必须有多个
应该是:

SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
WHERE E.SSN IN (SELECT D.ESSN
                FROM DEPENDENT AS D
                WHERE E.FNAME = D.DEPENDENT_NAME 
                  AND D.SEX = E.SEX);
如果你问是否可以写为一个
加入
,是这样的:

SELECT e.FNAME, e,LNAME
FROM EMPLOYEE AS e
WHERE EXISTS(SELECT * FROM DEPARTMENT AS d WHERE e.SSN = d.MGR_SSN)
   AND EXISTS (SELECT * FROM DEPENDENT AS d WHERE d.ESSN = e.SSN);
SELECT DISTINCT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
JOIN DEPENDENT D
  ON E.SSN = D.ESSN
 AND E.FNAME = D.DEPENDENT_NAME 
 AND D.SEX = E.SEX
第二个,再次太多
是,您可以检查NULL,但需要使用
左连接

SELECT E.FNAME, E.LNAME
FROM EMPLOYEE AS E
LEFT JOIN DEPENDENT D
  ON E.SSN = D.ESSN
WHERE D.ESSN IS NULL   -- IF doesnt have any match, will only have a NULL row
第三个不能有两个
,其中
需要

SELECT FNAME, LNAME
FROM EMPLOYEE
WHERE EXISTS (SELECT * FROM DEPARTMENT WHERE SSN = MGR_SSN)
  AND EXISTS (SELECT * FROM DEPENDENT  WHERE ESSN = SSN);

第一个
exists
告诉您employee也是一名经理。第二个
exists
告诉您employee有一个dependent

对于第二季度,您可以执行
左外连接dependents D ON…
其中D.essn为NULL
。我认为当前的语法更好,但这样也会更好work@CptMisery我的意思是不修改它e查询很重要;不清楚OP的意思。@Ueerdo这是一个很好的解释,它更有意义。但是关于Q1,我仍然有一些不明白的地方。你能解释一下该查询的WHERE子句吗?我不理解它背后的逻辑。为什么用“WHERE e.SSN IN”代替WHERE EXISTS(“在此处插入查询的其余部分”))?另外,ESSN如何与子查询的结果进行比较?@iHoaxe请参阅在Q1部分下的编辑中添加了更多解释。@uuerdo这一点现在更有意义了。但是关于Q1,我仍然有一些不明白的地方。你能解释一下该查询的WHERE子句吗?我不明白其背后的逻辑。为什么使用“WHERE E.SSN IN”而不是WHERE EXISTS(“在此处插入查询的其余部分”)此外,ESSN与子查询结果的比较情况如何?您可以使用
中的
编写相同的条件,并使用
中的
存在
将您的
SSN
依赖的
中的
性别相同的
姓名
存在的
进行类似的比较