【问题标题】:SQL select for many to many relationship using binding table使用绑定表的多对多关系的 SQL 选择
【发布时间】:2017-09-22 22:54:34
【问题描述】:

我正在努力在图片上写一个选择图表。

我想做的是写一个选择,它将显示汽车维修的详细信息。正如您在表 Repairs 中看到的那样,只有 2 个属性,但我不确定是否需要添加更多属性,尤其是来自 employees_listparts_list 的属性,因为我想通过它的 @ 显示每辆车的维修数据987654326@。维修数据是指维修id、车辆plate_number、所有从事维修工作的员工以及维修中使用的所有零件。如果我的图表有误,请帮我修复它,由于多对多关系和绑定表的使用,我不知道如何为此编写 select。

【问题讨论】:

  • 是的,很难进行大选择并将每个数据连接在一起,但是如果您想要更具体的内容,您应该在问题中指定您到底想从数据库中选择什么。
  • 我要选择的是我提到的所有修复数据。维修数据是指维修编号、车牌、所有使用的零件、所有参与维修的员工。另外,我不太确定在这种情况下是否需要绑定表,因为即使它的多对多关系,它总是不是实时的多对多,所以如果没有绑定表不是更容易/可能吗?

标签: sql database postgresql select


【解决方案1】:

这并不像看起来那么难。

首先,显然,我们必须选择汽车:

select vehicles.* from vehicles

那么,我们一起来维修吧:

select 
    vehicles.* 
from vehicles
    inner join repairs on vehicles.id = repairs.vehicle.id

我们不需要resule set中的repairs数据,所以我们只是加入它,但在'select'部分没有提及。

然后我们必须加入维修所需的零件,以及有关零件本身的信息:

select 
    vehicles.* 
from vehicles
    inner join repairs on vehicles.id = repairs.vehicle.id
    inner join parts_list on parts_list.repair_id = repairs.id
    inner join parts on parts_list.part_id = parts.id

对于该查询,我们得到的行数相当于维修所需的零件数量。但是如果我们将它们全部聚合到 json 列中,在代码中处理这些数据会更容易。所以在结果集中我们会看到类似的东西: vehicle_id, vehicle_part, parts_needed_as_json

让我们汇总一下:

select 
    vehicles.*, json_agg(parts.*) as parts_needed 
from vehicles
    inner join repairs on vehicles.id = repairs.vehicle_id
    inner join parts_list on parts_list.repair_id = repairs.id
    inner join parts on parts_list.part_id = parts.id
group by vehicles.id, repairs.id

现在您可以为员工添加相同的逻辑:

select 
    vehicles.*, 
    json_agg(parts.*) as parts_needed,
    json_agg(employes.*) as employees_needed
from vehicles
    inner join repairs on vehicles.id = repairs.vehicle.id
    inner join parts_list on parts_list.repair_id = repairs.id
    inner join parts on parts_list.part_id = parts.id
    inner join employees_list on employes_list.repair_id = repairs.id
    inner join employees on employees_list.employee_id = employees.id
group by vehicles.id, repairs.id

顺便说一句,我建议您将表格重命名为小写和单数。 比如:“维修”、“员工”和“车辆”;

另外,将绑定表命名为:“repair_part”和“repair_employee”。 有些人甚至建议按字母顺序排列该名称中的相关表,例如:'employee_repair' 和'part_repair',但我认为这不是必需的;

也许这是一个品味问题,但在大多数情况下,这会导致更具可读性的查询。

也就是说,上面的查询看起来像:

select 
    vehicle.*, 
    json_agg(part.*) as parts_needed,
    json_agg(employee.*) as employees_needed
from vehicle
    inner join repair on vehicle.id = repair.vehicle_id
    inner join parts_repair on parts_repair.repair_id = repair.id
    inner join part on parts_repair.part_id = part.id
    inner join employees_repair on employees_repair.repair_id = repair.id
    inner join employee on employees_repair.employee_id = employee.id
group by vehicle.id, repair.id

注意“开启”条件现在看起来多么优雅:parts_repair.part_id = part.id, parts_repair.part_id = part.id

抱歉英语不好

【讨论】:

  • 另外,您可能必须将“repair_date”添加到修复表中。
  • 我试图编辑您的代码,但我还没有编辑权限。您有一个未格式化的代码部分。嗯,那么最后的查询应该可以正常工作吗?
  • 是的,如果您有正确的表架构并调整了表名,它应该可以工作。
  • 在我可以尝试这个选择之前,我正在尝试实现一个表单来将员工和零件添加到维修中。如何在维修中添加多个员工和零件?
  • 好的。因此,基本上当我为车辆创建全新的维修时,我必须遵循以下步骤: 1. 选择哪些员工正在从事此维修工作。 2. 将那些有repair id 的员工插入employees_repair 表中。零件也一样。 1-1。选择此维修的零件。 2-2。将这些部分插入repair_parts 表中。然后我为您在上面的答案中写的选择做好了维修准备,对吗?我试图在我的视图和模型中实现这一点,请保持联系:) 谢谢
猜你喜欢
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 2017-09-26
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2017-08-25
相关资源
最近更新 更多