Mysql

根據條件加入第二張表

  • April 7, 2016

我正在將 Doctrine 用於一個有 3 個表連接在一起的網站。簡單來說,它們看起來像這樣

Contractor
- id
- name

ContractorJob
- id
- contractor_id
- job_id
- status

Job
- id
- start_date
- end_date

我想根據日期範圍將 Jobs 加入 Contractors,但您可以看到,唯一的方法是通過 ContractorJob 表。這意味著 ContractorJob 和 ContractorJob 之間的簡單內連接本質上是隨機的,因此 ContractorJob 和 Job 之間的後續連接大多是無用的。

如何使用 start_date 和 end_date 作為條件將 Contractor 加入 Job?

偽查詢如下

select from contractor c
left join ContractorJob cj on cj.contractor_id = c.id
left join job j with j.contractor_job = cj.id and j.start_date < :start_date and j.end_date > :end_date
where j.id is null

(查找在給定日期範圍內沒有工作的所有承包商)

*注意:Doctrine 是一個 Web 框架數據庫管理器,用於處理低級查詢處理,以便應用程序可以使用更多高級功能。它允許您說出query.innerJoin('a.second_table', 'b')並進行正確的連接

查詢有幾個問題

  • select清單不見了。
  • 連接語法需要ON,而不是WITHa JOIN b ON <some condition>
  • 缺少on條件(您正確辨識為 和 之間的任意/隨機連接ContractorContractorJob
  • 程式碼和設計之間存在列名不匹配:(Job.contractor_jobvs. Job.id)。哪個是正確的?

如何用LEFT JOIN / IS NULL. 括號是多餘的,僅用於使連接更清晰:

select 
   c.*
from 
       Contractor as c
   left join
       ( 
           ContractorJob as cj
       inner join 
           Job as j 
       on  
               j.id = cj.job_id 
           and j.start_date < :start_date 
           and j.end_date > :end_date
       )
   on 
       c.id = cj.contractor_id
where 
   cj.contractor_id is null ;

如何編寫NOT EXISTS我覺得更容易掌握的方法:

select c.*
from Contractor as c
where not exists
   ( select * 
     from ContractorJob as cj
       inner join Job as j 
       on  j.id = cj.job_id 
     where j.start_date < :start_date 
       and j.end_date > :end_date
       and c.id = cj.contractor_id
   ) ;

引用自:https://dba.stackexchange.com/questions/134669