mysql - 查询是否正确

标签 mysql sql

我有 6 个表(SQL Fiddle):

CREATE TABLE Department(
    Dname varchar(10),
    Dnumber int(5),
    Mgrno int(5),
    PRIMARY KEY(Dnumber)
    );

CREATE TABLE Employee(
    Fname varchar(20),
    Lname varchar(20),
    Empno int(5),
    Bdate date,
    Address varchar(10),
    Salary float(5),
    Dnumber int(5),
    PRIMARY KEY(Empno),
    FOREIGN KEY(Dnumber) REFERENCES Department(Dnumber)
    );


CREATE TABLE Location(
    Dnumber int(5),
    Dlocation varchar(10),
    PRIMARY KEY(Dlocation),
    FOREIGN KEY(Dnumber) REFERENCES Department(Dnumber)
    );

CREATE TABLE Project(
    Pname varchar(10),
    Pnumber int(5),
    Location varchar(10),
    Dnumber int(5),
    PRIMARY KEY(Pnumber),
    FOREIGN KEY(Dnumber) REFERENCES Department(Dnumber)
    );

CREATE TABLE Timesheet(
    Empno int(5),
    Pnumber int(5),
    Hours_per_day int(5),
    FOREIGN KEY(Empno) REFERENCES Employee(Empno),
    FOREIGN KEY(Pnumber) REFERENCES Project(Pnumber)
    );

 CREATE TABLE Dependent(
    Empno int(5),
    Dependent_name varchar(10),
    DOB date,
    Sex varchar(5),
    Relationship varchar(10),
    FOREIGN KEY(Empno) REFERENCES Employee(Empno)
    );

我被要求编写一个查询来检索在项目编号 30、40、50 上工作的所有员工的详细信息

这是我的尝试:

      SELECT * FROM Employee JOIN Timesheet
      ON  Employee.Empno = Timesheet.Empno 
      WHERE (Pnumber = 30 OR Pnumber = 40 OR Pnumber = 50)

我在 WHERE 子句之后执行条件是否合适?

题目是笔试的,所以没有提供任何数据集。

提前致谢!

最佳答案

是的,WHERE 子句中的条件似乎有效。

有很多表定义,但我们没有看到 Works_on 表的任何定义。我希望这实际上是对 Timesheet 表的引用。

请注意,连接操作会导致为一个员工返回多行;此查询将为时间表中的每个匹配行返回 Employee 行。

我建议限定所有 列引用,即使它们在语句中没有歧义。这有助于 future 的读者,也可以防止在将同名列添加到另一个表时查询中断。

此外,我建议放弃 SELECT 列表中的 *,并明确列出要返回的列。或者,如果我们必须使用 * 来返回所有列,请使用表名(或表别名)对其进行限定。


如所写,查询将返回参与过任何一个项目的员工列表。参与项目 30 和 40 但未参与项目 50 的员工将包括在内。

对该要求的另一种解释是只返回那些参与过所有三个项目的员工。该结果需要不同的查询。

这是满足该规范的一种(相当冗长的)可能方法:

SELECT e.*
  FROM Employee e
 WHERE EXISTS ( SELECT 1 
                  FROM Timesheet t1
                 WHERE t1.empno = e.empno
                   AND t1.pnumber = 30
              ) 
   AND EXISTS ( SELECT 1
                  FROM Timesheet t2
                 WHERE t2.empno = e.empno
                   AND t2.pnumber = 40
              ) 
   AND EXISTS ( SELECT 1
                  FROM Timesheet t3
                 WHERE t3.empno = e.empno
                   AND t3.pnumber = 50
              ) 

还有其他查询模式也可以满足规范。

例如,在 HAVING 子句中使用聚合表达式...

SELECT e.*
  FROM ( SELECT t.empno 
           FROM Timesheet t
          WHERE t.pnumber in (30,40,50)
          GROUP
             BY t.empno
         HAVING COUNT(DISTINCT t.pnumber) = 3
       ) q
  JOIN Employee e
    ON e.empno = q.empno 
 ORDER
    BY e.empno

或者,正如@MKhalidJunaid 所建议的,我们可以使用条件聚合...

SELECT e.*
  FROM ( SELECT t.empno
           FROM Timesheet t
          GROUP
             BY t.empno
         HAVING MAX(IF( t.pnumber = 30 ,1,0))
            AND MAX(IF( t.pnumber = 40 ,1,0))
            AND MAX(IF( t.pnumber = 50 ,1,0))
       ) q
  JOIN Employee e
    ON e.empno = q.empno
 ORDER
    BY e.empno

关于mysql - 查询是否正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50646099/

相关文章:

php - 如何在mysql中显示两个日期之间的小时数

java - 捕获导致表溢出的 ORACLE 查询

mysql - 如何在mysql中使用空白值创建唯一键?

mysql - INTERSECT 优于子查询吗?

php - 将 Wordpress Longtext 值转换为有效日期

mysql - 查询中的重复列名

java - Hibernate:更新表查询不起作用

php - Laravel:如何查询多个间接相关的表?

sql - oracle如何将不同行的文本合并到一个表中

mysql,重新格式化选择语句中的数据