【问题标题】:Parent-child sorting父子排序
【发布时间】:2016-05-17 11:27:55
【问题描述】:

我正在尝试对包含父行和子行的表进行排序。排序应始终基于父行执行,但子行应始终紧跟在父行之后。表格数据格式为

[
{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 查询并显示在数据表中,因此无论是客户端还是服务器端都可以对其进行排序。

与多排序无关(下面的评论)

【问题讨论】:

  • 请添加您目前尝试过的代码。
  • Henders:这不是 array_multisort 场景。 array_multisort 按多维排序。同样可以通过 mysql order by 或默认数据表行为来实现。我需要一个简单的一维排序,除了某些行需要聚集在一起(即跟随父级的组的子级),而不管逻辑排序顺序如何。按组排序,类型将导致正确的行为,但前提是按组排序是所需的结果。按任何其他列排序是这里的问题。
  • Ruben:到目前为止,我还没有想出任何合理的工作代码。 PHP、Laravel、DataTables 和连接适配器 (Yajra\Datatables) 都有带有回调的用户排序选项,但我需要引用比较范围之外的项目(在我的示例中按名称比较项目 2 和 3 是不可能的而不取名称考虑到第 1 项)。

标签: php laravel sorting datatables eloquent


【解决方案1】:

使用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'}
    ]
});

有关代码和演示,请参阅 this jsFiddle

【讨论】:

  • 不完全。这将父顺序锁定到位并且仅对子行进行排序,例如组 A 总是在 B 之前,这不是反向名称排序 (y,x,z,q) 的正确顺序。实际上,我并不关心子订单,父订单是关键。
【解决方案2】:

无法弄清楚如何在 SQL、DataTables 回调/排序器(尽管插件将是一个可行的选项)、Eloquent 回调或 Yajra DataTables 适配器选项中做到这一点。所以我只好用蛮力的方式。

  1. 使用 sql 按预期列排序
  2. 单独的主/子(债务/担保)行
  3. 查找每个子行的主记录以获得正确的排序索引,并为“真实”顺序创建一个新的索引列

            $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;
            }
    

【讨论】:

    【解决方案3】:

    SQL 中对此的一般解决方案是通过多个列进行自连接和排序,包括它是否是父列。在 OP 的情况下,假设一个数据表 dt 是一个别名,意思是 tables 意思是 sort):

    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
    

    【讨论】:

      猜你喜欢
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多