2016-07-14 18 views
5

Dies ist eine Suchfunktion, die jedes Mitglied mit ihrem letzten registrierten Jahr zurückgibt.Laravel verschachtelte Join-Abfragen mit Abfrage-Generator

Ich habe es mit einem Aufruf DB :: raw() arbeiten. Aber es kann nicht mit dem Abfrage-Generator arbeiten.

Arbeits Code:

$query = DB::table('membership as m'); 
$query->join(
    DB::raw(
     '(SELECT my.* 
     FROM membership_years my 
     INNER JOIN (
      SELECT member_id,MAX(membership_year) AS max_my 
      FROM membership_years 
      GROUP BY member_id 
     ) my2 
     ON my.member_id = my2.member_id 
     AND my.membership_year = my2.max_my 
     ) my' 
    ) 
,'m.id','=','my.member_id'); 

Mein Versuch, auf Query Builder Code:

$query = DB::table('membership as m'); 
$query->join('membership_years as my', 
    function($j1){ 
    $j1->join('membership_years as my2', 
     function($j2){ 
     $j2->where('my.membership_year','=','MAX(my2.membership_year)') 
     ->on('my.member_id','=','my2.member_id'); 
     } 
    )->on('m.id','=','my.member_id'); 
    } 
); 

Der resultierende Fehler ist:

Call to undefined Methode Illuminate \ Database \ Query \ JoinClause :: join()

Ich bin mir nicht sicher, ob dies daran liegt, dass die $j2 nicht mehr Zugriff auf die Join-Methode hat?

Raw MySQL-Abfrage:

SELECT my.membership_year,m.* 
FROM membership AS m 
INNER JOIN 
    (
     SELECT my1.* 
     FROM membership_years my1 
     INNER JOIN 
     (
      SELECT member_id,MAX(membership_year) AS max_my 
      FROM membership_years 
      GROUP BY member_id 
     ) my2 
     ON my1.member_id = my2.member_id 
     AND my1.membership_year = my2.max_my 
    ) my 
ON m.id = my.member_id 
ORDER BY m.id ASC 

Antwort

2

Way 1. Sie Teil der Abfrage mit Builder schreiben:

$query = DB::table('membership as m') 
     ->select('my.membership_year', 'm.*') 
     ->join(DB::raw('(
      SELECT my1.* 
      FROM membership_years my1 
      INNER JOIN (
       SELECT member_id, MAX(membership_year) AS max_my 
       FROM membership_years 
       GROUP BY member_id 
      ) my2 
      ON my1.member_id = my2.member_id 
      AND my1.membership_year = my2.max_my 
     ) my'), 
     'm.id', '=', 'my.member_id') 
     ->orderBy('m.id'); 

Way 2. Sie können auch Unterabfragen schreiben und toSql() Methode verwenden:

$sub1 = DB::table('membership_years') 
    ->select('member_id', DB::raw('MAX(membership_year) AS max_my')) 
    ->groupBy('member_id'); 

$sub2 = DB::table('membership_years as my1') 
    ->select('my1.*') 
    ->join(DB::raw('(' . $sub1->toSql() . ') my2'), 
      function ($join) { 
       $join 
        ->on('my1.member_id', '=', 'my2.member_id') 
        ->on('my1.membership_year', '=', 'my2.max_my'); 
      }); 

$query = DB::table('membership as m') 
    ->select('my.membership_year', 'm.*') 
    ->join(DB::raw('(' . $sub2->toSql() . ') my'), 'm.id', '=', 'my.member_id') 
    ->orderBy('m.id'); 
Verwandte Themen