php - Laravel 4,困惑的 Eloquent 连接查询

标签 php mysql sql laravel eloquent

我正在从事一个有点困惑的项目,其中数据库的结构是:

Object
id, title, description, url ... [and some more columns]

ObjectMeta
object_id, variable, value

所以让我们给你:

Object: 1, 'Cool Book', 'This cool book is just for you!', ...

Object Meta:
1, 'author_name', 'John Doe'
1, 'released', 2014
1, 'price', 23.22
1, 'url', 'http://amazon.com/coolbook'
1, 'genre', 3

所以我需要执行查询:

拉出类型为 3 的所有对象,然后按发布日期对这些对象进行排序。

$objs = static::Active()
->where('object', '=', $object)
->where('category','=',$category)
->whereIn('site_id', array(self::$site_id, 0))
->leftJoin('object_meta', function($join)
{
  $join->on('object.id','=', 'object_meta.content_id');
})
->where('object_meta.variable', 'genre')
->where('object_meta.value', 3);
->where('object_meta.variable', 'released');
->orderBy('object_meta.value', 'desc');
->groupBy('object.id')
->paginate(20);

即使有很多这样的书,此查询也有 0 个结果。我知道第二个 object_meta.variable 在这里是有罪的。我该如何编写这个查询才能使其工作?

非常感谢您的帮助。

-- 编辑

我已经创建了解决方法,但这真的非常糟糕(有趣的是,我发誓上面的查询已经工作了一个月左右)。

$objs = static::Active()
->where('object', '=', $object)
->where('category','=',$category)
->whereIn('site_id', array(self::$site_id, 0))
->leftJoin('object_meta', function($join)
{
  $join->on('object.id','=', 'object_meta.content_id');
})
->where('object_meta.variable', 'genre')
->where('object_meta.value', 3);
->groupBy('object.id')
->get();

foreach($objs as $obj)
{
  $obj->id = $obj->object_id;
    $objs_meta = ObjectMeta::where('object_id',$obj->object_id)->get();
    foreach($objs_meta as $obj_meta)
    {
      $variable = $obj_meta->var;
      $obj->$variable = $obj_meta->value;
    }
}
$objs = $objs->sortBy(function($role){
  return $role->released;
});
$objs = Paginator::make($objs->toArray(), sizeof($objs), $limit);

最佳答案

您需要内部联接 (join()),而不是 leftJoin(),并且您需要它两次:

$objs = static::Active()
 ->where('object', '=', $object)
 ->where('category','=',$category)
 ->whereIn('site_id', array(self::$site_id, 0))

 ->join('object_meta as genre', function ($join) {
   $join->on('object.id', '=', 'genre.content_id')
      ->where('genre.variable', '=', 'genre')
      ->where('genre.value', '=', 3);
 })
 ->join('object_meta as released', function ($join) {
   $join->on('object.id', '=', 'released.content_id')
      ->where('released.variable', '=', 'released');
 })

 ->orderBy('released.value', 'desc');
 ->select('object.*', 'released.value as released')

 ->distinct()
 // or group by, doesn't matter in your case
 // ->groupBy('object.id')

 ->paginate(20);

然后,您的对象将拥有具有适当值的附加属性released

<小时/>

根据评论:

如果您想动态添加联接,那么我建议如下所示的范围:

public function scopeGenre($query, $value)
{
   $query->join('object_meta as genre', function ($join) use ($value) {
       $join->on('object.id', '=', 'genre.content_id')
          ->where('genre.variable', '=', 'genre')
          ->where('genre.value', '=', $value);
     });
}

然后:

$query->where(..)->genre(3)->...

关于php - Laravel 4,困惑的 Eloquent 连接查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24910930/

相关文章:

mysql - Strongloop:用[and]和[or]条件一起过滤数据

PHP 和 mysql : how can i make selected option stay selected in s Combo after submit

sql - 限制 2 列的组合记录

Sql:一个日期的平均值

SQL 星号(*) 所有可能的用途

php - Magento:是什么导致重新索引……为什么它会中断?

PHP注册表单不插入

php - MySQL 数据库中的数据在网站中无法正确显示

php - 在 mysqli 中更改主机属性

mysql - docker run mysql 图像命令不起作用 [MacBook Pro M1]