SELECT列值为NEVER x的行

时间:2018-12-24 16:06:08

标签: mysql

我有一个链接到另一个表的表。 一个表保存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具有活动路由,因此不在此选择之列。

2 个答案:

答案 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