我正在尝试对具有父行和子行的表进行排序。排序应始终基于父行执行,但子行应始终紧跟在父行之后。表格数据采用格式
[
{name: 'xxx', group: 'A', type: 'parent'},
{name: 'yyy', group: 'B', type: 'parent'},
{name: 'zzz', group: 'A', type: 'child'},
{name: 'qqq', group: 'A', type: 'child'}
]
因此,按名称排序,正确的顺序是xxx、qqq、zzz、yyy。
数据来自Laravel/Eloquent ajax查询,并显示在datatables表中,因此可以在客户端或服务器端对其进行排序。
与多端口无关(下面的注释)
使用orderFixed
选项始终在任何其他列之前/之后对某一列应用排序。
例如:
var table = $('#example').DataTable({
ajax: {
url:'https://api.myjson.com/bins/4n6ey',
dataSrc: ''
},
orderFixed: {
pre: [[1, 'asc'], [2, 'desc']]
},
columns: [
{ data: 'name' },
{ data: 'group' },
{ data: 'type'}
]
});
有关代码和演示,请参阅此jsFiddle。
无法在SQL、DataTables回调/排序器(尽管插件是一个可行的选项)、Eloquent回调或Yajra DataTables适配器选项中找到如何做到这一点。所以我采取了暴力的方式。
- 使用sql按预期列排序
- 单独的主/子(债务/担保)行
-
查找每个子行的主记录以获得正确的排序索引,并为"真实"订单创建一个新的索引列
$dataTable_column_map = $claimPortfolio->getColumnMap(); $claimPortfolioLines = $claimPortfolio->lines()->orderBy($dataTable_column_map[$request->get('order')[0]['column']]['name'], $request->get('order')[0]['dir'])->get(); $claimPortfolioLines = ClaimPortfolioService::orderGuarantees($claimPortfolioLines); $claimPortfolioLines = ClaimPortfolioService::filterLines($claimPortfolioLines, Input::get('search.value')); Session::put('claimPortfolioLineIdList', $claimPortfolioLines->lists('id')->toArray()); return Datatables::of($claimPortfolioLines) ->order(function() { return true; // cancel built-in ordering & filtering }) ->filter(function() { return true; }) ->make(true); public static function orderGuarantees(Collection $claimPortfolioLines) { $claimPortfolioLinesGuarantees = $claimPortfolioLines->filter(function ($claimPortfolioLine) { return $claimPortfolioLine->line_type == 'GUARANTEE'; }); $claimPortfolioLines = $claimPortfolioLines->filter(function ($claimPortfolioLine) { return $claimPortfolioLine->line_type == 'DEBT'; }); foreach ($claimPortfolioLines as $idx_line => $claimPortfolioLine) { $claimPortfolioLine->sortOrder = $idx_line; foreach ($claimPortfolioLinesGuarantees as $idx_guaranteeLine => $claimPortfolioLineGuarantee) { if ($claimPortfolioLineGuarantee->contract_no == $claimPortfolioLine->contract_no && $claimPortfolioLine->line_type == 'DEBT') { $claimPortfolioLineGuarantee->sortOrder = "{$idx_line}.{$idx_guaranteeLine}"; $claimPortfolioLines->push($claimPortfolioLineGuarantee); } } } $claimPortfolioLines = $claimPortfolioLines->sortBy('sortOrder'); return $claimPortfolioLines; }
SQL中的一般解决方案是自联接并按多列排序,包括是否为父列。在OP的情况下,假设数据表d
(t
是别名,表示表,s
表示排序):
SELECT t.*
FROM d AS t
INNER JOIN d AS s
ON s.group = t.group
AND t.type = 'parent'
ORDER BY s.name, t.type = 'parent' DESC, t.name