如何将许多语句 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,但我很困惑。因为存在很多说法。有PREPARE
、EXECUTE
、SET
、DEALLOCATE
等,可以看上面的查询
如何将其转换为 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();
【讨论】:
我想问。如果我使用这样的原始查询,我该如何使用paginate
、where
和orderBy
?
还有一个。如何从该查询返回结果?
对于WHERE
和ORDER 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()->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?的主要内容,如果未能解决你的问题,请参考以下文章
如何将此查询从SQL(mysql)转换为Eloquent(Laravel)
将 MariaDB 语句转换为 Laravel4 Eloquent-Query