左表是我查询的结果。我需要将它排序为正确的表格。
如果order by p_id
我需要level >= 2
。右表的蓝框是order by
的目标。
有可能吗?当然这是一个例子。实际数据是数百,真正需要排序。
我经常搜索,但是找不到相同的案例。
编辑:此表格将以java.util.ArrayList
的形式返回。如果这种“排序依据”不可能,可以在java.util.ArrayList
吗?
答案 0 :(得分:3)
我确信在MySQL的一个查询中不可能。
在右边的图表中,订购分两个步骤完成:
按ID排序
如果级别> = 2
在MySQL中这很难做到,因为您需要识别块然后迭代它们,分别对每个块进行排序。
我做过类似的事情,需要在块内进行排序,然后从那些有序块中进行选择。您可以查看here,但正如我所说,我认为SQL代码非常复杂,涉及5个临时表。您可能需要更少的临时表,但它仍然是一个非常复杂的过程,非常慢且难以维护。
“实际数据是数百,真的需要排序。”
你有什么理由不能在代码中按照自己的意愿对其进行排序吗?
$blockStart = FALSE;
$count = 0;
foreach($dataArray as $data){
if($blockStart === FALSE){
$blockStart = $count;
}
if($data['level'] < 2){ //Block has finished
sortBlock($dataArray, $blockStart, $count);
$blockStart = $count;
}
$count++;
}
sortBlock($dataArray, $blockStart, $count - 1);
function sortBlock($dataArray, $indexStart, $indexEnd){
//Sort the elements of $dataArray, between $indexStart and $indexEnd inclusive
//by the value of p_id
}
尝试解决MySQL中的一般编程问题,当你可以在程序员时间的十分之一(也可能在Java中执行得更快)解决它时,这不是一个好的方法。
答案 1 :(得分:0)
可以在SQL中执行此操作,但在MySQL中这将是一个非常非常复杂的查询。这是方法。
(1)创建一个子查询,该子查询具有原始ID,并指示某事物是否在2级。此表中的ID将定义最终订单。
(2)接下来,为上表中的每个组创建一个单独的计数器。在其他数据库中,您将使用row_number()
。在我的SQL中,这需要一个相关的子查询。这提供了从id到新排序的映射。
(3)接下来,为每个组创建一个计数器,但这次是所需的顺序(非level2组的id,按您的排序规则)。
(4)将表格连接在一起以获得匹配。
(5)按原始身份订购。
这是一次尝试:
select altord.*
from (select t.*,
(select count(*) from t t2 where t2.id <= t.id and ((t2.level = 2 and t1.level = 2) or (t2.level <> 2 and t1.level <> 2))
) as seqnum
from t
) ord join
(select t.*,
(select count(*) from t t2 where (t2.id <= t.id and t2.level <> 2 and t.level <> 2) or (t2.level = 2 and t.level = 2 and (t2.pid < t.pid or t2.pid = t.pid and t2.id < t.id)))
) as seqnum
) altord
on ord.seqnum = altord.seqnum
order by ord.id
我不确定这个SQL是否正确,但这个想法可以在一个查询中实现。