在 PostgreSQL 中将 IN 与 JOIN 相结合
Combine a IN with a JOIN in PostgreSQL
table 有 id
机械、汽车和服务。 table 被命名为 mcs
。一个或多个机械师对同一辆车进行了维修。
逻辑是
- 我有一个机械师或汽车的 ID,我必须得到它的所有
服务
- 对于我得到的每一项服务,我都必须得到所有的机制和
也有相同服务的汽车
- 现在我拥有我想要的所有
id
机械和汽车
- 我想去他们对应的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;
table 有 id
机械、汽车和服务。 table 被命名为 mcs
。一个或多个机械师对同一辆车进行了维修。
逻辑是
- 我有一个机械师或汽车的 ID,我必须得到它的所有 服务
- 对于我得到的每一项服务,我都必须得到所有的机制和 也有相同服务的汽车
- 现在我拥有我想要的所有
id
机械和汽车 - 我想去他们对应的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;