2016-05-15 5 views
1

例では3つのテーブルがあります。ユーザー、grammar_learned、2つの結合と2つのカウントがラベリングを受け取ります

まずwords_learned:

CREATE TABLE grammar_learned 
(
    id INT(10) UNSIGNED PRIMARY KEY NOT NULL, 
    grammar_id INT(11) NOT NULL, 
    user_id INT(11) NOT NULL, 
); 

CREATE TABLE words_learned 
(
    id INT(10) UNSIGNED PRIMARY KEY NOT NULL, 
    word_id INT(11) NOT NULL, 
    user_id INT(11) NOT NULL, 
); 

CREATE TABLE users 
(
    id INT(10) UNSIGNED PRIMARY KEY NOT NULL, 
    name VARCHAR(255) NOT NULL, 
); 

そして、私のクエリ:

$users = User::leftJoin('words_learned', 'users.id', '=', 'words_learned.user_id') 
      ->leftJoin('grammar_learned', 'users.id', '=', 'grammar_learned.user_id') 
      ->selectRaw('users.*, count(words_learned.id) as learned_count, count(grammar_learned.id) as grammar_count') 
      ->groupBy('users.id')->orderBy("learned_count", "desc")->get(); 

私は私のテーブルに1行を持っているが(grammar_learnedと3行words_learnedテーブルではなく、クエリが3行を返します。 count)はwords_learned - grammar_learnedの場合は3行が正しく(1を返す必要があります)。 、まもなく

を助けてください、なぜ私は理解していない: 私はこの結果たい:

0 => array:4 [▼ 
    "id" => 1 
    "name" => "username" 
    "learned_count" => 3 
    "grammar_count" => 1 
    ] 

をしかし、私はここで

0 => array:4 [▼ 
    "id" => 1 
    "name" => "username" 
    "learned_count" => 3 
    "grammar_count" => 3 
    ] 
+0

あなたが一緒に複数のテーブルを結合するとき、あなたは、少なくとも上のあなたの条件に一致する行の数を引いて終了しようとしています'words_learned'です。返されたデータセットが現在どのように見えるのか、また上記の質問に実際にどのように表示されるのかのサンプルを含めることができますか?そうすれば、あなたが望むものを正確に把握することが容易になります。解決策は、サブクエリを使用するか、場合によっては選択リストの列にcase文を使用することです。 – gmiley

+0

@gmiley thx、私の質問 –

答えて

2

を取得し、以下を試してみてください。あなたの結合を削除し、代わりにサブクエリを使用しました...

$selectString = 'users.*, (select count(1) from words_learned wl where wl.user_id = users.id) as learned_count, '; 
$selectString = $selectString . '(select count(1) from grammar_learned gl where gl.user_id = users.id) as grammar_count '; 
$users = User::selectRaw($selectString)->groupBy('users.id')->orderBy("learned_count", "desc")->get(); 

これはまっすぐなSQLとして出てくるものです。あなたは次のことを持っていた:私は基本的にこれに変更

select u.*, count(wl.id) as word_cnt, 
     count(gl.if) as grammar_cnt 
from Users u 
join words_learned wl 
on wl.user_id = u.id 
join grammar_learned gl 
on gl.user_id = u.id 
group by u.id 
order by word_cnt desc; 

select u.*, 
     (select count(1) from words_learned wl where wl.user_id = u.id) as word_count, 
     (select count(1) from grammar_learned gl where gl.user_id = u.id) as grammar_count 
from users u 
group by u.id 
order by word_count desc; 
+0

が更新されました!どうもありがとう! –

関連する問題