2017-01-06 58 views
2

我試圖從基於相關表格的模型中獲取記錄時出現問題。用Eloquent查詢相關表格數據

我有兩個表一個叫leads和一個叫recycle_logs,我的應用程序將基本發送相同的記錄在leads表像每月一次,當它這樣做,我會存儲新紀錄recycle_logs

的問題是,我需要選擇所有leads與特定campaign_id值和具有特定status是從invalid不同,到目前爲止好,現在的問題是我需要的,只有當他們穿上,讓他們」如果與該特定lead關聯的最後recycleLog比之前的30更早,則可以使用與之關聯的任何recycleLogs

我目前看起來有點像這樣。

$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID) 
       ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO) 
       ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID) 
       ->orderBy(Lead::CREATED_AT, 'desc') 
       ->with(
        ['leadRecyclingLog' => function($query) { 
         $query->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays)) 
          ->orWhere(LeadRecyclingLog::ID, null); 
        }] 
       ) 
       ->get(); 

我究竟做錯了什麼?它始終選擇相同數量的記錄,無論我添加或刪除recycleLogs

我已經設法通過原始SQL查詢完成,我會在下面發佈以防萬一它幫助任何人,我仍然想要知道如何在Eloquent/Query Builder中做到這一點。

SELECT * FROM `leads` LEFT JOIN `lead_recycling_logs` ON `leads`.`guid` = `lead_recycling_logs`.`original_lead_guid` WHERE `leads`.`campaign_id` = :campaignID AND `leads`.`duplicated` = 0 AND `leads`.`lead_status` != :invalidStatus AND (`lead_recycling_logs`.`id` IS NULL OR `lead_recycling_logs`.`created_at` < :recyclingDate) ORDER BY `leads`.`created_at` DESC 

回答

1

試試這個:

$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID) 
    ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO) 
    ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID) 
    ->orderBy(Lead::CREATED_AT, 'desc') 
    ->where(function($q) { 
     $q->whereHas('leadRecyclingLog', function($q) { 
      $q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays)); 
     }) 
     ->orWhereHas('leadRecyclingLog', '<', 1); // Where count of the relationship is smaller than 1 
    })->get(); 

我假設查詢的第一部分運行良好(直到關係)。

你在找什麼是->whereHas(relationship),而不是->with(relationship)->with(relationship)會將關聯的結果附加到原始模型(對原始模型的查詢不會受到->with()的影響)。 ->whereHas(relationship)按條件過濾原始模型。

+0

orWhereDoesntHave不是查詢生成器的方法,因此,這也不起作用。我已經設法在簡單的MySQL原始查詢中複製我想要的東西,它工作得很好,如果有幫助,我會將其添加到問題中。 –

+0

哦,對不起。我編輯它來糾正。 – devk

+0

orWhereHas的第二個參數必須是一個關閉 –

1

得到它通過工作@devk的幫助

$leads = $this->leadModel->where(Lead::CAMPAIGN_ID, $this->campaignID) 
     ->where(Lead::DUPLICATED, Lead::DUPLICATED_NO) 
     ->where(Lead::LEAD_STATUS, "!=" ,Lead::LEAD_STATUS_INVALID) 
     ->orderBy(Lead::CREATED_AT, 'desc') 
     ->where(function($q) { 
      $q->whereHas('leadRecyclingLog', function($q) { 
       $q->where(LeadRecyclingLog::CREATED_AT, '<', (new Carbon())->subDays($this->configRecyclingDays)); 
      }) 
       ->doesntHave('leadRecyclingLog', 'or'); 
     })->get();