Mysql 嵌套联接以创建自定义动态列

Mysql 嵌套联接以创建自定义动态列,mysql,Mysql,我有一张表,如下所示: ------------------------------- | ID | Modello | Targa | ------------------------------- | 1 | IVECO | XA123WE | ------------------------------- | 2 | IVECO | CF556XD | ------------------------------- | 3

我有一张表,如下所示:

-------------------------------
| ID  |   Modello |   Targa   | 
-------------------------------
| 1   |   IVECO   |   XA123WE |     
-------------------------------
| 2   |   IVECO   |   CF556XD |   
-------------------------------
| 3   |   FIAT    |   AS332ZZ | 
-------------------------------
| 4   |   GOLF    |   GF567YU | 
-------------------------------
对于我没有的每辆车,一个或多个修订版I_veicolo(修订版)(日期过期的
较大的版本是我需要根据今天的日期检查修订版是否仍然有效的版本)

根据我上面的例子(今天是2019-10-29):

车辆:ID=1的版本仍处于激活状态(2020-10-01),但未通过(通过成功=0)

车辆:ID=2的修订版仍然有效(2019-11-25)并通过(通过成功=1)

车辆:ID=3尚未修订

车辆:ID=4有版本,但没有有效版本(最后一次在2017年10月20日到期),但最后一次通过检查(Pass_success=1)

我需要的是在查询结果上动态创建3个新的自定义列:

-------------------------------------------------------------------------------------------
| ID  |   Modello |   Targa   |  RevisionPresent | RevisionStillActive | LastRevisionPassed |
-------------------------------------------------------------------------------------------
| 1   |   IVECO   |   XA123WE |      true        |   true              |   false  
-------------------------------------------------------------------------------------------
| 2   |   IVECO   |   CF556XD |      true        |   true              |   true
-------------------------------------------------------------------------------------------
| 3   |   FIAT    |   AS332ZZ |       false      |   false             |  false
-------------------------------------------------------------------------------------------
| 4   |   GOLF    |   GF567YU |       true       |   false             |  true
-------------------------------------------------------------------------------------------
我试着从我以前的帖子开始:

但我对使用嵌套联接感到非常困惑

我试着开始拉小提琴,但我被语法错误卡住了:

这有两个问题

  • 别名
    a
    是为此子查询定义的,因此不能在子查询中引用它。但无论如何,您不需要限定子查询中的列—您在其他子查询中没有这样做,所以我不确定您为什么在本例中这样做
  • 您没有此联接的任何联接条件。MySQL对于何时需要连接条件有点不一致。但在这种情况下,你需要一个

在我用这两个更正测试了查询之后,它就工作了。

基本上,您只需要查看每个车辆的最新版本就可以生成该结果集

您可以使用相关子查询进行筛选:

select
    v.ID,
    v.Modello,
    v.Targa,
    (DataScadenzaRevisione >= now()) RevisionPresent,
    (DataScadenzaRevisione >= now() and EsitoPositivo = 1) RevisionStillActive,
    (EsitoPositivo = 1) LastRevisionPassed 
from 
    veicoli v
    left join revisioni_veicolo r 
        on r.veicoli_ID = v.ID
        and r.DataScadenzaRevisione = (
            select max(DataScadenzaRevisione) 
            from revisioni_veicolo r1 
            where r1.veicoli_ID = v.ID
    )
您可以使用中的示例数据检查结果

或者您可以使用窗口函数(这需要MySQL 8.0):


您需要表的左连接和条件聚合:

select v.ID, v.Modello, v.Targa,
  max(r.DataScadenzaRevisione is not null) RevisionPresent,
  coalesce(max(r.DataScadenzaRevisione >= current_date()), 0) RevisionStillActive,
  max(case when r.DataScadenzaRevisione = g.maxdate then r.EsitoPositivo else 0 end) LastRevisionPassed 
from veicoli v 
left join revisioni_veicolo r on r.veicoli_ID = v.id
left join (
  select veicoli_id, max(DataScadenzaRevisione) maxdate 
  from revisioni_veicolo
  group by veicoli_id
) g on g.veicoli_ID = v.id           
group by v.ID, v.Modello, v.Targa
请参阅。
结果:


你在使用MySQL 8.0吗?窗口函数会使这变得更容易。我在本地主机上使用MySQL 5.6.17,使用WAMP服务器进行测试。另外,我正在使用SQLyog软件获取一些基本查询。您好,谢谢您的简化代码!似乎有2个错误:ID=1的车辆有错误的修正仍然激活。ID=4的车辆有错误的修改。非常感谢。只有一个字段不正确:对于车辆4->LastRevisionPassed必须为true您能再次解释一下逻辑吗?对于所有4辆车,为什么结果应为0、1、0、1?嗨,为什么车辆ID=4没有修订活动…但车辆4的最后一辆(于2017年10月20日到期)通过=真。LastRevisionPassed基于每辆车的最新版本(不管是否过期)
select
    v.ID,
    v.Modello,
    v.Targa,
    (DataScadenzaRevisione >= now()) RevisionPresent,
    (DataScadenzaRevisione >= now() and EsitoPositivo = 1) RevisionStillActive,
    (EsitoPositivo = 1) LastRevisionPassed 
from 
    veicoli v
    left join revisioni_veicolo r 
        on r.veicoli_ID = v.ID
        and r.DataScadenzaRevisione = (
            select max(DataScadenzaRevisione) 
            from revisioni_veicolo r1 
            where r1.veicoli_ID = v.ID
    )
select
    v.ID,
    v.Modello,
    v.Targa,
    (DataScadenzaRevisione >= now()) RevisionPresent,
    (DataScadenzaRevisione >= now() and EsitoPositivo = 1) RevisionStillActive,
    (EsitoPositivo = 1) LastRevisionPassed 
from (
    select 
        v.*, 
        r.*, 
        row_number() over(partition by ID order by r.DataScadenzaRevisione desc) rn
    from veicoli v
    left join revisioni_veicolo r on r.veicoli_ID = v.ID
) where coaelesce(rn, 1) = 1
select v.ID, v.Modello, v.Targa,
  max(r.DataScadenzaRevisione is not null) RevisionPresent,
  coalesce(max(r.DataScadenzaRevisione >= current_date()), 0) RevisionStillActive,
  max(case when r.DataScadenzaRevisione = g.maxdate then r.EsitoPositivo else 0 end) LastRevisionPassed 
from veicoli v 
left join revisioni_veicolo r on r.veicoli_ID = v.id
left join (
  select veicoli_id, max(DataScadenzaRevisione) maxdate 
  from revisioni_veicolo
  group by veicoli_id
) g on g.veicoli_ID = v.id           
group by v.ID, v.Modello, v.Targa
| ID  | Modello | Targa   | RevisionPresent | RevisionStillActive | LastRevisionPassed |
| --- | ------- | ------- | --------------- | ------------------- | ------------------ |
| 1   | IVECO   | XA123WE | 1               | 1                   | 0                  |
| 2   | IVECO   | CF556XD | 1               | 1                   | 1                  |
| 3   | FIAT    | AS332ZZ | 0               | 0                   | 0                  |
| 4   | GOLF    | GF567YU | 1               | 0                   | 1                  |