从属表

现在让我们的查询复杂一点。让我们向我们的数据库添加一个新的任务表,其中包含我们员工的任务。让我们看看它包含哪些条目:

SELECT * FROM task

这样请求的结果:

ID emploee_id 姓名 最后期限
1个 1个 修复一个前端bug 2022-06-01
2个 2个 修复后端的一个bug 2022-06-15
3个 5个 买咖啡 2022-07-01
4个 5个 买咖啡 2022-08-01
5个 5个 会买咖啡 2022-09-01
6个 (无效的) 打扫办公室 (无效的)
7 4个 享受生活 (无效的)
8个 6个 享受生活 (无效的)

该表只有 4 列:

  • id — 唯一的任务编号(和表中的行);
  • employee_id — 分配任务的员工表中员工的 ID;
  • 名称― 任务的名称和描述;
  • deadline - 任务必须完成的时间。

注意一些细微差别。任务 N6 没有 employee_id,我们没有清洁工。任务在那里,但执行者不在。它发生了。

此外,任务 6-9 没有设定的截止日期。当必须定期和连续地完成一项任务时,就会发生这种情况。比如办公室每天都要打扫卫生,但你也需要每天享受生活:)

如果一个表使用另一个表的 ID,那么这样的表称为dependent

查询多个表

这里我们在任务表中看到有两个任务“享受生活”。我们怎么知道这些幸运儿是谁?

为此,在 SQL 中,您可以同时对两个表执行查询。一般来说,在SQL中,可以同时查询任意多张表。这种请求的一般格式是:

SELECT columns
FROM Table 1, table 2, tableN

重要的!如果您同时对多个表编写查询,那么您将得到所谓的表行的笛卡尔积。第一个表中的每一行将粘附到第二个表中的每一行,依此类推。

也就是说,如果第一个表中有 5 行,第二个表中有 10 行,那么总共有 50 行。在 Java 中,这个查询看起来像这样:

for (String row1 : table1)
{
	for (String row2 : table2)
   {
  	System.out.println(row1 + row2);
   }
}

让我们一次将查询写入两个表,看看会发生什么:

SELECT * FROM employee, task

这个查询的结果是:

ID 姓名 职业 薪水 年龄 ID 雇员 _ID 姓名 最后期限
1个 伊万诺夫伊万 程序员 100000 25 1个 1个 修复一个前端bug 2022-06-01
2个 彼得罗夫彼得 程序员 80000 23 1个 1个 修复一个前端bug 2022-06-01
3个 伊万诺夫谢尔盖 测试员 40000 三十 1个 1个 修复一个前端bug 2022-06-01
4个 拉比诺维奇·莫伊沙 导演 200000 35 1个 1个 修复一个前端bug 2022-06-01
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 1个 1个 修复一个前端bug 2022-06-01
6个 瓦斯卡 1000 3个 1个 1个 修复一个前端bug 2022-06-01
1个 伊万诺夫伊万 程序员 100000 25 2个 2个 修复后端的一个bug 2022-06-15
2个 彼得罗夫彼得 程序员 80000 23 2个 2个 修复后端的一个bug 2022-06-15
3个 伊万诺夫谢尔盖 测试员 40000 三十 2个 2个 修复后端的一个bug 2022-06-15
4个 拉比诺维奇·莫伊沙 导演 200000 35 2个 2个 修复后端的一个bug 2022-06-15
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 2个 2个 修复后端的一个bug 2022-06-15

我们总共有 48 行结果,但这里我只给出了 11 行。否则,空间就不够了。

注意三件事:

  • 具有相同名称的列:id这是employee表中的 id和task表中的 id 。
  • 每个表的行都是重复的。在左列中,ID 6 之后又是 ID = 1。
  • 我们有无意义的行,例如,id(来自 employee 表)为 6,而在同一行中,employee_id 为 1。

删除无意义的行

结果表中的行太多 ,这是employeetask两个表的所有行的笛卡尔积。

从逻辑上讲,如果行 employee_id 为 3,那么它应该只保留 employee 表中 id 为 3 的行。让我们尝试用 WHERE 来解决这个误解。

让我们写一个这样的查询:

SELECT * FROM employee, task 
WHERE emploee.id = task.emploee_id 

这个查询的结果是:

ID 姓名 职业 薪水 年龄 ID emploee_id 姓名 最后期限
1个 伊万诺夫伊万 程序员 100000 25 1个 1个 修复一个前端bug 2022-06-01
2个 彼得罗夫彼得 程序员 80000 23 2个 2个 修复后端的一个bug 2022-06-15
4个 拉比诺维奇·莫伊沙 导演 200000 35 7 4个 享受生活 (无效的)
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 3个 5个 买咖啡 2022-07-01
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 4个 5个 买咖啡 2022-08-01
5个 基连科阿纳斯塔西娅 办公室主管 40000 25 5个 5个 会买咖啡 2022-09-01
6个 瓦斯卡 1000 3个 8个 6个 享受生活 (无效的)

好消息是无意义的行已经消失:第一列的 id 始终等于 employee_id。

坏消息是没有分配给任何人的任务,例如打扫办公室,都没有了。他们的 employee_id 是 NULL,所以他们在 WHERE 完成后被丢弃。