2013-07-22 71 views
2

如何查詢與Eloquent,所有用戶沒有某種類型的證書?如何將其轉換爲一個很好的Eloquent查詢

Laravel 4

我有2個表:

users table: 
    ->id 
    ->name 


certificats table: 
    ->id 
    ->user_id 
    ->certificate_type 

我真的現在有了這個掙扎了幾個小時。我試過的最後一件事是:

$users = User::with(array('certificate' => function($query) 
{ 
    $query->where('type','!=','SL'); 
}))->get(); 

這給了我所有的用戶,但我試圖讓所有的用戶沒有證書類型「SL」。

- 編輯: Spencer7593的原始查詢下面的作品。但我沒有得到雄辯的查詢工作。

SELECT u.* 
FROM users u 
LEFT 
JOIN certificates c 
ON c.user_id = u.id 
AND c.type = 'SL' 
WHERE c.user_id IS NULL 

的關係:

public function certificate(){ 
    return $this->hasMany('Certificate'); 
} 

public function certificate(){ 
    return $this->belongsTo('User'); 
} 
+0

是否有幫助:$ query-> where('certificate_type','!=','SL'); – Maximus2012

+0

不,它不:(我也試過'certificate.type' – mauricehofman

+0

'type'指證書表中的列,所以應該是正確的。你不在其他地方重新定義'$ users'變量這可能會覆蓋這個?你在'用戶'模型中有適當的功能來將它與證書相關嗎? – user1669496

回答

1

的SQL得到的結果設置要相當簡單。

SELECT u.* 
    FROM users u 
    LEFT 
    JOIN certificates c 
    ON c.user_id = u.id 
    AND c.type = 'SL' 
WHERE c.user_id IS NULL 

這是一種稱爲「反連接」的熟悉模式。基本上,這是一個匹配行的LEFT JOIN外觀,以及來自users的沒有匹配的行,然後篩選出所有確實匹配的行,並且我們留下了users沒有的行比賽。

訣竅是要獲得雄辯爲你生成SQL。爲了得到雄辯要做到這一點,你需要告訴雄辯做一個LEFT JOIN,然後添加一個WHERE子句,

也許這樣的事情會接近:

->left_join('certificate AS c', function($join){ 
     $join->on('c.user_id','=','user.id'); 
     $join->and_on('c.type','=','SL'); 
    }) 
->where_null('c.user_id') 

隨訪

(爲了那些可能沒有閱讀評論的人的利益)

克拉斯泰斯特(OP),報告語義問題試圖在Eloquent(在上面的答案中):left_join需要被替換爲leftJoin,而and_on未被識別。 (後者可能是我發明的,基於與whereand_whereor_where使用的慣例。)

$users = DB::table('users') 
    ->select('users.id','users.name') 
    ->leftJoin('certificate AS c', function($join){ 
    $join->on('c.user_id','=','user.id'); 
    $join->on('c.type','=','SL'); 
    }) 
    ->where_null('c.user_id'); 
+0

你的原始查詢正在工作,但是當我嘗試你的雄辯解決方案時,我得到一個大對象,但我不知道如何使用。將left_join更改爲leftJoin,and_on沒有工作(不存在?)。 所以我得到了這個: $ users = DB :: table('users') - > select('users.id','users.name') \t - > leftJoin('certificate',function($ join){ $ join- >上( 'certificate.user_id', '=', 'user.id'); $ join-> on('certificate.type','!=','SL'); }) - > where_null('certificate.user_id'); dd($ users); – mauricehofman

+0

@Klaas Terst:我希望原始查詢能夠正常工作;這是一種稱爲「反連接」的熟悉模式。在這種情況下,我們並不真的有興趣從證書中返回任何列;它只是從'users'表中返回列。我絕對不是口才的專家;我只是刺探了一些我認爲可能會生成該SQL語句的東西。 – spencer7593

+0

@Klaas Terst:那應該是對'SL'的平等測試,而不是不平等測試。您希望「標記」來自具有匹配「SL」行的用戶的行。 – spencer7593

0

我相信這個問題是在你的人際關係。

模型

class User extends Eloquent 
{ 
    public function certificates() 
    { 
     return $this->hasMany('Certificate'); 
    } 
} 

class Certificate extends Eloquent 
{ 
    public function user() 
    { 
     return $this->belongsTo('User'); 
    } 
} 

控制器

$users = User::with(array('certificates' => function($query) 
{ 
    $query->where('type','!=','SL'); 
}))->get(); 
return View::make('yourView')->with('users',$users); 

查看

@foreach($users as $user) 
    {{ $user->name }} // User's name 
    @foreach($user->certificates as $certificate) 
     {{ $certificate->certificate_type }} // Certificate type shouldn't be 'SL' 
    @endforeach 
@endforeach 

我希望這有助於!

相關問題