【问题标题】:Laravel - How to create a query with where clause using subquery?Laravel - 如何使用子查询创建带有 where 子句的查询?
【发布时间】:2021-05-05 20:15:25
【问题描述】:

我正在尝试使用 Laravel 生成此查询:

select mygames.id, mygames.name, mygames.slug, mygames.cover from mygames 
left join mygame_mygenre on mygames.id = mygame_mygenre.mygame_id 
left join mygame_myplatform on mygames.id = mygame_myplatform.mygame_id 
where mygame_mygenre.mygenre_id in (8, 9, 31, 32, 33) 
and mygame_myplatform.myplatform_id in (3, 6, 14, 34, 37, 39, 46, 48, 72, 130) 
and mygames.id <> 1990
and mygames.summary is not null 
and (select count(mygame_id) from mygame_myplatform where mygame_id = mygames.id) > 1 
group by mygames.id, mygames.name, mygames.slug, cover 
order by RAND() 
limit 6

我当前的代码是:

$games = DB::table('mygames')
            ->leftjoin('mygame_mygenre', 'mygames.id', '=', 'mygame_mygenre.mygame_id')
            ->leftjoin('mygame_myplatform', 'mygames.id', '=', 'mygame_myplatform.mygame_id')
            ->select('mygames.id', 'mygames.name', 'mygames.slug', 'cover')
            ->when($genres_id, function ($query, $genres_id) {
                return $query->whereIn('mygame_mygenre.mygenre_id', $genres_id);
            })
            ->when($platforms_id, function ($query, $platforms_id) {
                return $query->whereIn('mygame_myplatform.myplatform_id', $platforms_id);
            })
            ->where('mygames.id', '<>', $this->id)
            ->whereNotNull('mygames.summary')
            ->where(function ($query) {
                $query->selectRaw('count(mygame_id)')
                ->from('mygame_myplatform')
                ->where('mygame_id', 'mygames.id');
            }, '>', 1)
            ->groupBy('mygames.id', 'mygames.name', 'mygames.slug', 'cover')
            ->inRandomOrder()
            ->take(6)
            ->get();

此代码不起作用,因为在闭包函数中我无法将 mygames 表的名称与 id 字段一起传递。 Laravel 被解释为文本参数而不是 table.field

->where(function ($query) {
                    $query->selectRaw('count(mygame_id)')
                    ->from('mygame_myplatform')
                    ->where('mygame_id', 'mygames.id'); <<<<<<<<<<<<<
                }, '>', 1)

我尝试使用'use ()',但也没有用。

你能帮帮我吗?

【问题讨论】:

  • 尝试使用 Eloquent Relations 和 whereHas()、with() 等函数,而不是使用 DB 助手类。一旦你定义了有效的关系,with() 和 whereHas() 可以让你的生活变得简单并且代码易于理解。

标签: mysql laravel eloquent


【解决方案1】:

这里我假设您正在尝试比较 2 列,对吗?

->where('mygame_id', 'mygames.id');

在这种情况下,请使用whereColumn/orWhereColumn 方法。

->whereColumn('mygame_id', 'mygames.id')

【讨论】:

    【解决方案2】:

    这是因为你必须使用whereColumn 方法来实现这一点。 https://laravel.com/docs/8.x/queries#additional-where-clauses 另一种解决方案是使用whereRaw 方法。 见:

    DB::table('mygames')
                ->select(['mygames.id', 'mygames.name', 'mygames.slug', 'mygames.cover'])
                ->leftJoin('mygames_mygenre', 'mygames.id', '=', 'mygame_mygenre.mygame_id')
                ->leftJoin('mygame_myplatform', 'mygames.id', '=', 'mygame_myplatform.mygame_id')
                ->whereIn('mygame_mygenre.mygenre_id', [8, 9, 31, 32, 33])
                ->whereIn('mygame_myplatform.myplatform_id', [3, 6, 14, 34, 37, 39, 46, 48, 72, 130])
                ->where('mygames.id', '<>', 1990)
                ->whereNotNull('mygames.summary')
                ->where(1, '<', function ($query) {
                    $query->selectRaw('COUNT(mygame_id)')
                        ->from('mygame_myplatform')
                        ->whereColumn('mygame_id', 'mygames.id');
                })
                ->groupBy('mygames.id', 'mygames.name', 'mygames.slug', 'cover')
                ->inRandomOrder()
                ->take(6)
                ->get();
    

    【讨论】:

      【解决方案3】:

      看起来类似于@jascar_destin 的答案,但在分组依据中,您必须指定从哪个表中挑选封面,除非封面在其他表而不是 mygames 上不存在。

      DB::table('mygames AS mg')
              ->leftJoin('mygame_mygenre AS mgmg', 'mgmg.mygame_id', '=', 'mg.id')
              ->leftJoin('mygame_myplatform AS mgmp', 'mgmp.mygame_id', '=', 'mg.id')
              ->select(['mg.id', 'mg.name', 'mg.slug', 'mg.cover'])
              ->whereIn('mgmg.my_genre_id', [8, 9, 31, 32, 33])
              ->whereIn('mgmp.my_platform_id'. [3, 6, 14, 34, 37, 39, 46, 48, 72, 130])
              ->where('mg.id', '<>', 1990)
              ->whereNotNull('mg.summary')
              ->where(1, '<', function ($query) {
                  $query->selectRaw('COUNT(mygame_id)')
                      ->from('mygame_myplatform')
                      ->whereColumn('mygame_id', 'mg.id');
              })
              ->groupBy('mg.id', 'mg.name', 'mg.slug', 'mg.cover')
              ->inRandomOrder()
              ->take(6)
              ->get();
      

      【讨论】:

        猜你喜欢
        • 2013-10-19
        • 1970-01-01
        • 2021-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多