2016-11-16 58 views
0

我有一个数据透视表'game_genre'(带有game_id和genre_id)。游戏和流派模型具有类似于以下示例的关系belongsToManyLaravel Eloquent - 查询生成器找不到具有函数的列

我一直在试图收集包含60和55的genre_id在一起的游戏。我一直使用下面的SQL查询得到正确的结果,但是当使用下面的查询生成器时,我最终在使用having()函数时发现列未找到错误。

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'genre_id' in 'having clause'

林不知道怎么回事构建查询生成器?

MODEL:

class Game extends Model 
{  
    public function genres() 
    { 
     return $this->belongsToMany('App\Genre'); 
    } 
} 

SQL:

SELECT * 
FROM game_genre 
WHERE genre_id = 55 OR genre_id = 60 
GROUP BY game_id 
HAVING COUNT(DISTINCT genre_id) = 2; 

控制器:

$game = Game::whereHas('genres', function ($query) 
{ 
    $query->where('genre_id', '55') 
     ->orWhere('genre_id', '60') 
     ->groupBy('game_id') 
     ->having('genre_id','=', 2); 
})->get(); 
+0

- > having('genre_id','=',2);应该是 - > having('genre_id','=',2) –

+0

或者尝试 - > havingRaw('genre_id = 2') –

+0

如果你想获得gener_jd的游戏60 & 55;你可以把关系函数(gener)在放置语句的Game模型中返回$ this-> belongsToMany(Gener :: class,'game_gener');然后尝试从这个查询中得到结果$ games = Game :: gener() - > where('gener_id',55) - > orWhere('gener_id',60) - > get();确保你将关系函数设置为静态,否则你必须调用关系函数关于对象; –

回答

4

你在你的HAVING状态忘记聚合函数(在这种情况下COUNT):

$query->where('genre_id', '55') 
    ->orWhere('genre_id', '60') 
    ->groupBy('game_id') 
    ->havingRaw('COUNT(DISTINCT genre_id) = 2'); 

而不是增加几个where()orWhere()您查询,您还可以使用whereIn()这需要一个数组:

$myArray = [55,60]; 
$query->whereIn('genre_id', $myArray) 
    ->groupBy('game_id') 
    ->havingRaw('COUNT(DISTINCT genre_id) = 2'); 
+0

这似乎比重复一个'whereHas()'像Amits方法略微整齐,我倾向于使用这个。林想知道你是否知道为什么原始的SQL工作,并使用标准的'()函数不检测列? – Orbitall

+1

@Orbitall我的猜测是你的'SELECT'列表中没有'genre_id'。 'HAVING'只能使用'SELECT'列表中,'GROUP BY'子句中或在聚合函数中使用的列。 – simon

+0

@Orbitall哦,标准的'having()'在这种情况下不起作用,因为它仅适用于列名作为第一个参数。这意味着你不能使用'COUNT',这就是为什么你需要使用'havingRaw()'。 – simon

0

您可以使用下面的查询来获取Games包含的60genre_id55

$games = Game::whereHas('genres', function ($query) { 
       $query->where('genre_id', '55'); 
      }) 
      ->whereHas('genres', function ($query) { 
       $query->where('genre_id', '60'); 
      }) 
      ->get(); 
+0

这个看起来好像比'havingRaw()'方法在循环中效果更好。 – Orbitall