문제

I have a strange set of circumstances that I don't seem to be able to build a query for. Help is appreciated.

Here is my query as it currently sits:

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 and $date are properly subtituted with valid data. What I want to happen is to have the columns from the vehicle table in the response no matter what. If I enter a valid date this works. If I enter a date that is not spanned in the insurance table, I still want to get the general info about the vehicle, but instead I get an empty record set.

I thought that putting the IS NULL clauses might help this, but the problem is that the LEFT JOIN does match at least one record in the insurance table, but consequently there is no matching policy that spans the requested date.

How can I improve my query?

도움이 되었습니까?

해결책

I think you should move your ins conditions into the ON statement

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}'

다른 팁

I don't use MySQL but if I was doing this on SQL Server I would probably create a subquery that had your insurance details in with the where clause in there, then join vehicles to that.

The syntax my be wrong here but something like this.

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}' 

This way the insurance details are filtered prior to the left join to the vehicle.

There are more elegant ways but this way usually saves on my limited brain power!

Al.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top