【问题标题】:Having with parentheses in Laravel Query Builder在 Laravel 查询生成器中使用括号
【发布时间】:2014-02-21 05:42:35
【问题描述】:

我正在将我的应用程序迁移到 Laravel 4,但我遇到了一个非常重要的查询,原始查询是:

'select m.* from vn_mensagem m'
            . ' INNER JOIN vn_mensagem_item i ON i.mensagem_id = m.mensagem_id '
            . 'INNER JOIN vn_mensagem_destino d ON d.mensagem_id = m.mensagem_id '
            . 'WHERE d.usuario_id = ' . $user->id . ' AND m.lida = 0 '
            . 'AND i.data > "' . $timestamp . '" '
            . 'group by d.mensagem_id '
            . 'HAVING (count(i.mensagem_item_id) > 1 OR m.usuario_id != ' . $user->id . ')'
            . 'ORDER BY i.data DESC'

我尝试使用 Laravel 查询生成器重现该查询,结果如下:

$mensagens = DB::table('mensagem')
                    ->select('mensagem.*')
                    ->join('mensagem_item', 'mensagem.mensagem_id', '=', 'mensagem_item.mensagem_id')
                    ->join('mensagem_destino', 'mensagem.mensagem_id', '=', 'mensagem_destino.mensagem_id')
                    ->where('mensagem_destino.usuario_id', $user->id)
                    ->where('lida', 0)
                    ->where('mensagem_item.data', '>', $timestamp)
                    ->groupBy('mensagem_destino.mensagem_id')
                    ->having(function($query) {
                        $query->where(DB::raw('count(mensagem_item.mensagem_item_id)'), '>', 1)
                        ->orWhere('mensagem.usuario_id', '!=', $user->id);
                    })                        
                    ->orderBy('mensagem_item.data', 'desc')->get();

然后我得到以下错误:

{"error":{"type":"ErrorException","message":"strtolower() expects parameter 1 to be string, object given","file":"\/var\/www\/laravel\/php\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Grammar.php","line":49}}

如何在 Laravel Query Builder 中创建父级之间的 HAVING 条件?

【问题讨论】:

    标签: mysql laravel laravel-4 eloquent


    【解决方案1】:

    having() 不接受回调,你可以使用havingRaw()

    【讨论】:

      【解决方案2】:

      你的问题在这里:

      DB::raw('count(mensagem_item.mensagem_item_id)')

      这将返回一个整数,而不是 Laravel 所期望的字段名称字符串。

      查看 Illuminate/Database/Grammar.php,您可以看到查询是如何构建的。

      您可能希望使用 DB::unprepared 进行完全 RAW 查询。见这里:https://stackoverflow.com/a/17876877/146602

      【讨论】:

      • 未准备方法的语法是什么?我在文档中找不到它,我试图 $mensagens = DB::unprepared('select ...');但我收到错误“无法在其他无缓冲查询处于活动状态时执行查询。考虑使用 PDOStatement::fetchAll()。或者,如果您的代码只针对 mysql 运行,您可以通过设置 PDO:: 来启用查询缓冲。 MYSQL_ATTR_USE_BUFFERED_QUERY 属性。"
      猜你喜欢
      • 1970-01-01
      • 2014-05-06
      • 2021-01-29
      • 2017-12-28
      • 2019-05-06
      • 2017-03-29
      • 1970-01-01
      • 2018-07-03
      相关资源
      最近更新 更多