在 PostgreSQL 中将 IN 与 JOIN 相结合

Combine a IN with a JOIN in PostgreSQL

table 有 id 机械、汽车和服务。 table 被命名为 mcs。一个或多个机械师对同一辆车进行了维修。

逻辑是

  1. 我有一个机械师或汽车的 ID,我必须得到它的所有 服务
  2. 对于我得到的每一项服务,我都必须得到所有的机制和 也有相同服务的汽车
  3. 现在我拥有我想要的所有id机械和汽车
  4. 我想去他们对应的tables,根据他们的 ids,我想得到他们的名字和不是的车牌 在机制中可用 table

我有点迷茫。我猜我已经走到一半了。这就是我现在所拥有的。

select distinct mcs.mechanic_id, mcs.car_id from mcs where mcs.service_id in 
(select mcs.service_id from mcs where mcs.car_id = 1) 
;

现在,这行得通了,我有了我想要的所有 ID,我必须以某种方式将它们用于以下查询

select car.name, mechanic.name, car.plate from 
car full join mechanic
on
car.id = mcs.car_id
and 
mechanic.id = mcs.mechanic_id

我不知道如何继续下去。像

select car.name, mechanic.name, car.plate from 
car full join mechanic
on
car.id = mcs.car_id
and 
mechanic.id = mcs.mechanic_id
IN
select distinct mcs.mechanic_id, mcs.car_id from mcs where mcs.service_id in 
(select mcs.service_id from mcs where mcs.car_id = 1) 
;

但这不起作用,我不想有很多循环。

有什么建议吗?

谢谢

我认为这就是您所需要的:

with cteServices as (
select distinct
  service_id
from
  mcs
where
  car_id = 1 -- or mechanic_id = ?
)
select
  mcs.mechanic_id
  ,mechanic.name
  ,mcs.car_id
  ,car.plate
from
  mcs
  inner join
  cteServices on mcs.service_id = cteServices.service_id
  inner join
  car on mcs.car_id = car.car_id
  inner join
  mechanic on mcs.mechanic_id = mechanic.mechanic_id;

http://sqlfiddle.com/#!17/cb7db/5

第一部分是一个通用的 table 表达式 (CTE),其中 return 是与 car_id 关联的所有服务。您还可以将查询更改为特定的 mechanic_id.

此 CTE 然后用于将第二部分中的 mcs 连接到 return 所有出现的那些 service_ids。然后您可以将 mcs 连接到汽车和机械师 tables 以获得您想要的额外数据。

编辑: 要在最终查询中排除选定的汽车,您可以添加一个 where 子句,例如 "car.car_id <> 1"

with cteServices as (
select distinct
  service_id
from
  mcs
where
  car_id = 1 -- or mechanic_id = ?
)
select
  mcs.mechanic_id
  ,mechanic.name
  ,mcs.car_id
  ,car.plate
from
  mcs
  inner join
  cteServices on mcs.service_id = cteServices.service_id
  inner join
  car on mcs.car_id = car.car_id
  inner join
  mechanic on mcs.mechanic_id = mechanic.mechanic_id
where
  car.car_id <> 1;

http://sqlfiddle.com/#!17/cb7db/12