2

ここに画像の説明を入力

左の表は私のクエリの結果です。そして、それを正しいテーブルとしてソートする必要があります。

私はする必要がありorder by p_idますlevel >= 2。右表の青枠が対象ですorder by

出来ますか?もちろん一例です。実際のデータは数百あり、実際に並べ替える必要があります。

いろいろ検索しましたが、同じケースは見つかりませんでした。

edit : このテーブルは として返されjava.util.ArrayListます。この種の「オーダー・バイ」が可能でない場合、それは可能java.util.ArrayListですか?

4

2 に答える 2

3

MySQLの1つのクエリでは不可能だと確信しています。

右側の図では、注文は 2 つの別々のステップで行われています。

  1. IDで並べ替え

  2. レベル >= 2 の場合、各ブロックを p_id で並べ替えます

ブロックを識別し、それらを繰り返し処理して、各ブロックを個別にソートする必要があるため、MySQL でこれを行うのは非常に困難です。

ブロック内での順序付けが必要な場合に同様のことを行い、それらの順序付けられたブロックから選択しました。ここでそれを見ることができますが、私が言ったように、その 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 ではプログラマーの 10 分の 1 の時間で解決できる場合 (そしておそらく実行速度も向上する可能性があります) は、従うべき良い道ではありません。

于 2013-01-10T02:12:42.477 に答える
0

SQL でこれを行うことは可能ですが、MySQL では非常に複雑なクエリになります。これがアプローチです。

(1) 元の ID と、何かがレベル 2 にあるかどうかのインジケータを持つサブクエリを作成します。このテーブルの ID は、最終的な順序を定義します。

(2) 次に、この上の表のグループごとに個別のカウンターを作成します。他のデータベースでは、row_number(). 私の SQL では、これには相関サブクエリが必要です。これにより、id から新しい順序へのマッピングが提供されます。

(3) 次に、各グループのカウンターを作成しますが、今回は必要な順序で作成します (非 level2 グループの場合は ID、順序付けのルールによる)。

(4) テーブルを結合して一致させます。

(5) 元のIDで注文。

ここに試みがあります:

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 が正しいかどうかはわかりませんが、アイデアは 1 つのクエリで実装できます。

于 2013-01-10T03:04:32.750 に答える