MySQL左联接,联接表中没有令人满意的匹配

MySQL左联接,联接表中没有令人满意的匹配,mysql,join,Mysql,Join,我有一组奇怪的情况,我似乎无法构建查询。谢谢你的帮助 以下是我当前的查询: SELECT * FROM vehicle LEFT JOIN vehicle_insurance AS ins ON vehicle.id=ins.vehicle_id WHERE vehicle.id='{$vid}' AND ( ins.effective<='{$date}' OR ins.effective IS NULL ) AND ( ins.expires>='{$date}' OR i

我有一组奇怪的情况,我似乎无法构建查询。谢谢你的帮助

以下是我当前的查询:

SELECT * 
FROM vehicle 
LEFT JOIN vehicle_insurance AS ins
ON vehicle.id=ins.vehicle_id
WHERE vehicle.id='{$vid}' 
AND ( ins.effective<='{$date}' OR ins.effective IS NULL )
AND ( ins.expires>='{$date}' OR ins.expires IS NULL )
$vid和$date正确替换为有效数据。我想要做的是,不管发生什么,都要在响应中包含vehicle表中的列。如果我输入一个有效的日期,这是有效的。如果我在保险表中输入了一个未跨越的日期,我仍然希望获得有关车辆的一般信息,但我会得到一个空记录集

我认为放置IS NULL子句可能会有帮助,但问题是左连接至少与保险表中的一条记录匹配,但因此没有跨越请求日期的匹配策略


如何改进我的查询?

我不使用MySQL,但如果我在SQL Server上这样做,我可能会创建一个子查询,其中包含您的保险详细信息和where子句,然后将车辆加入其中

我的语法在这里可能是错误的,但类似这样的东西

SELECT * 
FROM vehicle 
LEFT JOIN 
(
   SELECT * FROM vehicle_insurance 
   WHERE ( ins.effective<='{$date}' OR ins.effective IS NULL )
     AND ( ins.expires>='{$date}' OR ins.expires IS NULL ) 
) AS ins
ON vehicle.id=ins.vehicle_id
WHERE vehicle.id='{$vid}' 
这样,在左连接到车辆之前会过滤保险详细信息

还有更优雅的方式,但这种方式通常可以节省我有限的脑力


Al.

我不使用MySQL,但如果我在SQL Server上这样做,我可能会创建一个子查询,其中包含您的保险详细信息和where子句,然后将车辆加入其中

我的语法在这里可能是错误的,但类似这样的东西

SELECT * 
FROM vehicle 
LEFT JOIN 
(
   SELECT * FROM vehicle_insurance 
   WHERE ( ins.effective<='{$date}' OR ins.effective IS NULL )
     AND ( ins.expires>='{$date}' OR ins.expires IS NULL ) 
) AS ins
ON vehicle.id=ins.vehicle_id
WHERE vehicle.id='{$vid}' 
这样,在左连接到车辆之前会过滤保险详细信息

还有更优雅的方式,但这种方式通常可以节省我有限的脑力


Al.

我认为您应该将ins条件移到ON语句中

SELECT * 
FROM vehicle 
LEFT JOIN vehicle_insurance AS ins
ON vehicle.id=ins.vehicle_id AND ins.effective<='{$date}' AND  ins.expires>='{$date}'
WHERE vehicle.id='{$vid}'

我认为你应该把你的移民局的条件写进ON声明中

SELECT * 
FROM vehicle 
LEFT JOIN vehicle_insurance AS ins
ON vehicle.id=ins.vehicle_id AND ins.effective<='{$date}' AND  ins.expires>='{$date}'
WHERE vehicle.id='{$vid}'

如果您针对ins.effective和ins.expires日期进行测试,并且每个测试中的日期都没有返回true,那么无论发生什么情况,您都不会得到任何结果,因为没有与测试匹配的记录。不要使用*,使用显式列名,即vehicle.name、vehicle.vin、ins.effective、ins.expires。向我展示一个你希望以表格格式返回的数据的例子,这样我就可以更好地了解你想要得到的结果。有趣的用例。我认为这应该是您希望在应用程序代码或存储过程中检查的内容,按原样运行查询,如果没有返回结果,则只使用vid重新运行。你也可以试试这样的。如果vehicle.id='{$vid}'或ins.effective='{$date}'或ins.expires为空,但这可能会给您带来不想要的结果如果您针对ins.effective和ins.expires日期进行测试,那么在每个测试中该日期都不会返回true,那么无论发生什么情况,您都不会得到任何结果,因为没有任何记录与测试匹配。不要使用*,使用显式列名,即vehicle.name、vehicle.vin、ins.effective、ins.expires。向我展示一个你希望以表格格式返回的数据的例子,这样我就可以更好地了解你想要得到的结果。有趣的用例。我认为这应该是您希望在应用程序代码或存储过程中检查的内容,按原样运行查询,如果没有返回结果,则只使用vid重新运行。你也可以试试这样的。其中vehicle.id='{$vid}'或ins.effective='{$date}'或ins.expires为空,但这可能会给您带来不想要的结果这确实会以我希望的方式成功响应它们。这确实会以我希望的方式成功响应它们。