简体   繁体   English

MYSQL INNER JOIN 获得 3 种类型的结果

[英]MYSQL INNER JOIN to get 3 types of result

I have a table VEHICLES like this:我有一张这样的桌子车辆:

-------------------------------------------------------
| ID  |   Brand   |   License_plate      |  Model      |
-------------------------------------------------------
| 1   |   IVECO   |   XA123WE            |  GRANDX    |
| 2   |   IVECO   |   CF556XD            |  TOURS     |
| 3   |   FIAT    |   AS332ZZ            |  Punto     |
-------------------------------------------------------

For each vehicle I have one or multiple INSURANCE (the one with bigger date is the one I need to check if insurance is still active or not based on today date)对于每辆车,我有一个或多个保险(日期较大的那个是我需要根据今天的日期检查保险是否仍然有效的那个)

-------------------------------------
| ID  |   vehicle_ID   |   Expire   |
-------------------------------------
| 1   |   1            | 2018-10-19 |
| 2   |   1            | 2019-10-20 |
| 3   |   2            | 2019-11-25 |
| 4   |   2            | 2018-10-20 |
-------------------------------------

In my example above, assuming today is 2019-10-28 , insurance for vehicle with ID 1 is expired, insurance for vehicle with ID 2 is still active (2019-11-25), vehicles ID 3 has no insurance yet.在我上面的示例中,假设今天是2019-10-28 ,ID 1 车辆的保险已过期,ID 2 车辆的保险仍然有效(2019-11-25),车辆 ID 3 还没有保险。

I'm not sure how to build a unique query in PHP to get my result to search:我不确定如何在 PHP 中构建唯一查询以获取我的搜索结果:

  1. All vehicles ID with insurance expired (checking only the highest by date for each vehicle, if is < NOW() )所有带有保险的车辆 ID 都已过期(仅检查每辆车的最高日期,如果是 < NOW() )
  2. All vehicles ID with no insurance present所有没有保险的车辆ID

     SELECT V.ID FROM vehicles V JOIN insurance I ON V.ID = I.vehicle_ID WHERE....
  3. All vehicles ID with insurance still active (checking only the highest by date for each vehicle, if is >= NOW() )所有带有保险的车辆 ID 仍然有效(仅检查每辆车的最高日期,如果 >= NOW() )

You coudl try using left join for the two condition您可以尝试对这两个条件使用左连接

select  v.ID, v.Brand, v.Mode
    , ifnull(t1.max_expire_date, 'expired') expired
    ,  ifnull(t2.vehicle_ID , 'not present') not_present
    , case when t1.max_expire_date is not null then 'present' END AS present
from vehicles 
LEFT JOIN  (
  select  vehicle_ID, max(Expire) max_expire_date
  from  insurance 
  group by  vehicle_ID
) t1 on t1.vehicle_ID = v.id 
    AND t.max_expire_date >= date(NOW())
LEFT JOIN  (
  select  vehicle_ID
  from  insurance 
) t2 ON t2.vehicle_ID = v.id 

and if you want filter using a where condition you can't use the column alias but you should repeat the code如果您想使用 where 条件进行过滤,则不能使用列别名,但您应该重复代码

select  v.ID, v.Brand, v.Mode
    , ifnull(t1.max_expire_date, 'expired') expired
    ,  ifnull(t2.vehicle_ID , 'not present') not_present
    , case when t1.max_expire_date is not null then 'present' END AS present
from vehicles 
LEFT JOIN  (
  select  vehicle_ID, max(Expire) max_expire_date
  from  insurance 
  group by  vehicle_ID
) t1 on t1.vehicle_ID = v.id 
    AND t.max_expire_date >= date(NOW())
LEFT JOIN  (
  select  vehicle_ID
  from  insurance 
) t2 ON t2.vehicle_ID = v.id 
WHERE ifnull(t1.max_expire_date, 'expired')  = 'expired'

Using LEFT OUTER JOINs, you 3 queries could be done as:-使用 LEFT OUTER JOIN,您可以完成 3 个查询:-

SELECT vehicles.ID 
FROM vehicles 
INNER JOIN insurance i1 
ON vehicles.ID = i1.vehicle_ID 
LEFT OUTER JOIN insurance i2 
ON i1.vehicle_ID = i2.vehicle_ID 
AND i2.expire > i1.expire
WHERE i2.id IS NULL
AND i1.expire < NOW()

Here it does a left outer join for any later insurance expiry dates, and checks for i2.id being NULL to ensure no later expiry date is found, and then checks the found expiry date to check it has expired.在这里,它为任何以后的保险到期日期进行左外连接,并检查 i2.id 是否为 NULL 以确保找不到更晚的到期日期,然后检查找到的到期日期以检查它是否已过期。

SELECT vehicles.ID 
FROM vehicles 
LEFT OUTER JOIN insurance i1 
ON vehicles.ID = i1.vehicle_ID 
WHERE i1.id IS NULL

This just checks there is no matching insurance record这只是检查没有匹配的保险记录

SELECT vehicles.ID 
FROM vehicles 
INNER JOIN insurance i1 
ON vehicles.ID = i1.vehicle_ID 
LEFT OUTER JOIN insurance i2 
ON i1.vehicle_ID = i2.vehicle_ID 
AND i2.expire > i1.expire
WHERE i2.id IS NULL
AND i1.expire >= NOW()

Very similar to the first query, it does a left outer join for any later insurance expiry dates, and checks for i2.id being NULL to ensure no later expiry date is found, and then checks the found expiry date to check it has not expired.与第一个查询非常相似,它为任何以后的保险到期日期执行左外连接,并检查 i2.id 是否为 NULL 以确保没有找到以后的到期日期,然后检查找到的到期日期以检查它是否没有过期.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM