如何将许多语句 mysql 转换为 laravel eloquent?

Posted

技术标签:

【中文标题】如何将许多语句 mysql 转换为 laravel eloquent?【英文标题】:How can I convert many statement mysql to laravel eloquent? 【发布时间】:2019-01-21 03:55:10 【问题描述】:

mysql 查询如下:

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'ifnull(SUM(case when location_code = ''',
      location_code ,
      ''' then quantity end),0) AS `',
      location_code , '`'
    )
  ) INTO @sql
FROM
  item_details;
SET @sql = CONCAT('SELECT item_number,SUM(quantity) as "total_quantity", ', @sql, ' 
                  FROM item_details
                   GROUP BY item_number');

PREPARE stmt FROM @sql;
EXECUTE stmt;

DEALLOCATE PREPARE stmt;

我想将它转换为 laravel eloquent,但我很困惑。因为存在很多说法。有PREPAREEXECUTESETDEALLOCATE等,可以看上面的查询

如何将其转换为 laravel eloquent?

【问题讨论】:

没有人可以帮忙吗? 使用 eloquent 拉取基本的 select 语句结果,然后在 php 中做你的业务逻辑(ifnull 测试)可能会更容易。 @Luke G. 这并不像您想象的那么容易。看来你不知道laravel eloquent 你熟悉查询构建器和 Eloquent 的区别吗?我认为您在谈论查询构建器,而不是 Eloquent。 @SuccessMan,我认为我没有在 Eloquent 中看到过这种情况。正如 Jonas 所提到的,查询构建器可能是实现您想要的额外逻辑的解决方案。 【参考方案1】:

主要是原始查询:

DB::table('item_details')->selectRaw('GROUP_CONCAT(...) INTO @sql')->get();
DB::statement('SET @sql = CONCAT(...)');
DB::statement('PREPARE stmt FROM @sql');
DB::statement('EXECUTE stmt');
DB::statement('DEALLOCATE PREPARE stmt');

试试这个:

DB::table('item_details')->selectRaw('GROUP_CONCAT(...) INTO @sql')->get();
$sql = DB::selectOne('select @sql')->'@sql';
ItemDetails::select('item_number', DB::raw('SUM(quantity) as total_quantity'))
    ->selectRaw($sql)
    ->groupBy('item_number')
    ->get();

【讨论】:

我想问。如果我使用这样的原始查询,我该如何使用paginatewhereorderBy 还有一个。如何从该查询返回结果? 对于WHEREORDER BY,您可以添加任何您想要的原始SQL。分页可能要复杂得多。执行这样的查询通常是一个非常糟糕的主意,您应该考虑使用“普通”查询。 那么最好的解决方案是什么?我需要paginate。我实际上想使用普通查询,但我的查询是动态的。所以我很难转换成雄辩的 laravel 我认为我们应该专注于将其转换为“正常”查询。您能否提供一些背景信息来说明您为什么需要这样的动态查询?【参考方案2】:

您应该将您的查询作为一个 Mysql 过程并针对您的数据库运行它,我在下面对您的查询进行了微调,

DROP PROCEDURE IF EXISTS searchitems;
DELIMITER $$
CREATE PROCEDURE searchitems()
  BEGIN

 SET @@group_concat_max_len = 75000;
  SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT 
    CONCAT(
           'max(CASE WHEN location_code = ''',
           location_code,
           ''' THEN coalesce(quantity, 0) END) AS `',
           location_code, '`'
       )
  ) INTO @sql
FROM
  item_details;
SET @query := CONCAT('SELECT item_number,SUM(quantity) as "total_quantity", ', @sql, ' 
                  FROM item_details
                   GROUP BY item_number');

PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @@group_concat_max_len = 1024;

END $$
DELIMITER ;

然后使用像这样的查询生成器方法从 Laravel 控制器调用您的过程,

$queryResult = $db->prepare('call searchitems()'); 
$queryResult->execute(); 
$results = $queryResult->fetchAll(PDOConnection::FETCH_ASSOC); 
$queryResult->closeCursor(); 

然后将你的结果集转换成 Laravel 集合,然后你就可以像这样轻松地进行分页了,

 $results_collection = collect($results);
$currentPage = LengthAwarePaginator::resolveCurrentPage();
$perPage = 20;
$currentPageSearchResults = $results_collection->slice(($currentPage - 1) * $perPage, $perPage)->all();
$paginatedSearchResults = new LengthAwarePaginator($currentPageSearchResults, count($results_collection), $perPage);
$paginatedSearchResults->setPath($request->url());
$paginatedSearchResults->appends($request->except(['page']));

然后像这样返回视图

    return view('yourview')
           ->with('results',$paginatedSearchResults);

//or if ajax call

    $viewData =  view('yourview')
           ->with('results',$paginatedSearchResults)
           ->render();

     $response = [
           "Status" => "Success",
           "Content" =>   $viewData
     ];
     return response()->json($response);

在您的刀片视图模板中,您可以在 foreach 循环中访问数据并在表格或列表视图中呈现, 要显示分页,你可以这样做

//to render pagination is front end
<div class="row">
    <div class="col-md-offset-4">
        <?php echo $results->render(); ?>
    </div>
</div>  

但是我建议您缓存数据以避免重复调用过程并提高性能,因为如果您有数百万个数据,这种构建分页的方式会减慢您的应用程序, 如果你需要实现 Ajax 分页, 你可以参考this article

【讨论】:

太棒了。但存在错误:Undefined variable: db。我尝试更改为\DB::getPdo()-&gt;prepare(...,如下所示:imgur.com/06umZx3。我再次发现这样的错误:imgur.com/Wdb7DIP 请看这篇文章,我已经提到了你需要导入的命名空间,techalyst.com/links/read/135/…【参考方案3】:

这似乎是重复的 (How to create select dynamic fields from a table in mysql?)。

您在另一个线程上请求并获得了帮助,但在这里询问如何实际实施他们在那里给出的答案。 (我可能会补充说,询问时相当好斗。)

通常最好要求对您获得的代码进行澄清,作为给出问题的答案。

【讨论】:

这不是重复的。查询是一样的,但是这个问题的目的是不同的。上一个问题是mysql的问题。这个问题是mysql到laravel eloquent的转换问题 当我在另一个线程上阅读您的讨论时,您似乎无法使该代码正常工作。如果是这种情况,您将相同的代码交给我们并要求我们让它为您工作。这不是完全重复,但您要求我们处理代码,而不是要求原始海报帮助您这样做。 如果你这么想,那就看你自己了。在这里我只问我不知道的。如果你不回答这个问题,那也没关系。我自己试试

以上是关于如何将许多语句 mysql 转换为 laravel eloquent?的主要内容,如果未能解决你的问题,请参考以下文章

如何将此 MySQL 查询转换为 Laravel?

将 MySQL 查询转换为 Laravel 查询构建器代码

如何将此查询从SQL(mysql)转换为Eloquent(Laravel)

将 MariaDB 语句转换为 Laravel4 Eloquent-Query

如何将mysql中的select语句转换为java中的查询?

如何将带有子查询的 MySQL select 语句转换为同一张表的更新语句?