我有一个链接到另一个表的表。
一个表保存carriers
,另一张表保存routes
。
路由表有一个carrier_id
列,该列相互关联,还有一个status
字段,用于确定路由的活动状态,0
是活动状态。
我试图列出没有活动路线的承运人,这使我处于不稳定的境地,很容易选择根本没有路线的承运人,但是查询的第二方给我带来麻烦。
SELECT c.id
, c.title
FROM carriers c
LEFT
JOIN routes r
ON r.carrier_id = c.id
WHERE r.route_id IS NULL
OR (r.status > 0 AND r.carrier_id = c.id)
问题很明显-结果表出现误报-归档和未归档路由的运营商。我很确定SQL采用了某种构造,可以用来指定类似这样的内容:
if any of carrier.routes.status == 0 exclude carrier from selection
这几乎就是问题所在。
更新:有人要求我提供数据集和该数据集的预期结果,所以我在下面提供它:
个运营商:
--------------
| id | title |
--------------
| 1 | foo |
| 2 | bar |
| 3 | baz |
--------------
路线:
----------------------------
| id | carrier_id | status |
----------------------------
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 2 | 1 |
----------------------------
使用以下数据,应返回运营商2和3,因为3没有活动路由,两个都不具有2。但是,1具有活动路由,因此不在此选择之列。
答案 0 :(得分:2)
尝试这样
SELECT carrier.id, carrier.title
FROM carriers LEFT JOIN routes
ON routes.carrier_id = carrier.id and
(route.route_id IS NULL OR (route.status > 0)
请注意,Where (route.route_id IS NULL OR (route.status > 0)
子句将您的左联接隐式转换为内部联接
更好,更清洁的解决方案
Select * from carriers
Where exists
(
Select 1 from routes where routes.carrier_id = carrier.id and status != 0
) or carriers.route_id is null.
OP的笔记:我实际发现对我有用的是基于上述逻辑,并且是这样的:
Select * from carriers
Where exists
(
Select 1 from routes where routes.carrier_id = carrier.id and status != 0
) and not exists
(
Select 1 from routes where routes.carrier_id = carrier.id and status != 0
) or carriers.route_id is null.
答案 1 :(得分:0)
您可能需要尝试“左外部连接”,这将使左侧表中的记录不在右侧。因此,将显示所有没有记录的承运人。现在,您只需要添加一个条件routes.status> 0即可记录具有活动状态的路由。如下所示:
SELECT carrier.id, carrier.title FROM carriers
LEFT JOIN routes ON routes.carrier_id = carrier.id
WHERE routes.status > 0