2016-05-14 21 views
1

の正または負の整数に基づいてテーブルを注文します。MySQLの:私は<strong>MySQLの</strong>テーブルに列<strong><code>my_order</code></strong>と<strong><code>alt_order</code></strong>で<strong><code>example</code></strong>と呼ばれている列

は、ここで私が達成しようとしているものです:nullの

  • alt_order場合は、my_orderによって順番。
  • alt_orderがヌルでない場合は、my_orderで注文しますが、alt_orderの整数に基づいて上または下の行を配置します。

擬似コード:

SELECT * FROM `example` 
    ORDER BY 
     IF(`alt_order` IS NULL, `my_order`, [MOVE UP OR DOWN BASED ON `alt_order`]) 

理想的な出力:

+--------+----------+-----------+-------------------------------------+ 
| desc | my_order | alt_order | notes        | 
+--------+----------+-----------+-------------------------------------+ 
| Item 1 | 1  | NULL  | Ordered by `my_order`    | 
| Item 3 | 122  | -1  | Ordered by `my_order` + `alt_order` | <-- Move up one row 
| Item 2 | 50  | NULL  | Ordered by `my_order`    | 
| Item 4 | 127  | NULL  | Ordered by `my_order`    | 
| Item 5 | 205  | NULL  | Ordered by `my_order`    | 
+--------+----------+-----------+-------------------------------------+ 

試み:

SELECT * FROM `example` 
    ORDER BY 
     IF(`alt_order` IS NULL, `my_order`, `my_order` + `alt_order`) 

# The problem with using this method is that the value of `my_order` 
# has to be the same as the value of above it to work. 

何か助けや助言をいただければ幸いです。ありがとうございました。

編集:

alt_orderが正Nであれば、それはN行を下に移動する必要があります。一方、alt_order場合、それは、N行を上に移動する必要があり、N負です。

+0

*アイテム2 *が* alt_order = + 1 *の場合、あなたはどうしますか? –

+0

@PaulSpiegel 'alt_order'が正の** n **の場合、** n **行下に移動する必要があります。一方、 'alt_order'が負の** n **の場合、** n **行上に移動する必要があります。 –

+0

私はあなたの意見を忘れてしまったと思います。 * Item2:alt_order = + 1 * => * rowNr 3 *に移動し、* Item3 *は* rowNr 2 *を取得します。今* Item3 *は* alt_order = -1 *を持ちます。 * rowNr 1 *に移動しますか?要件が不完全になるケースは他にもたくさんあります。別の例:* Item2:alt_order = + 1 *と* Item3:alt_order = + 1 * - それらを2回スワップしますか? –

答えて

1

あなたが指定した結果は、行を2回並べることで実現できるようです。まず、my_orderで注文し、最初の「行番号」を割り当てます。次に、「行オフセット」によって調整された最初の「行番号」によって順序付けられた、2回目の通過を行います。 「行番号」と「行オフセット」は両方とも整数なので、それらを追加すると(rn = 2 + ro = 0)、衝突が発生します(rn = 3 ro = -1)。発注より多くの確定を行うために、我々は、以下のクエリはあなたのために働くか、正しい方向にあなたを送ることができ

SELECT s.desc 
     , s.my_order 
     , s.alt_order 
     , s.notes 
    FROM (SELECT @rn := @rn + 1 AS rn 
       , t.desc 
       , t.my_order 
       , t.alt_order 
       , t.notes 
      FROM `example` t 
      CROSS 
      JOIN (SELECT @rn := 0) i 
      ORDER BY t.my_order 
     ) s 
    ORDER 
    BY s.rn + IFNULL(s.alt_order,0.5) 
+0

私はそれが大好きです。だから私はこの仕組みを理解しようとしていますが、最後の 'ORDER BY'の最後に** 0.5 **を使った理由がわかりません。その特定の部分について説明してもらえますか? –

+0

注文をより確定させるために0.5を追加しました。 rn = 3で行を取得し、alt_orderが-1の場合、その行を「上に1」移動するには、rnとalt_orderを追加すると3-1 = 2となります。それはMySQLに同じ位置にある必要がある2つの行を与えます...それはコインがどんな順序になるかを投げることです。私はネクタイを壊すために0.5を追加しました。実際には "上に上がる"でしょう。 – spencer7593

+0

非常にクール!説明ありがとう。 –

0

調整する必要がありますすることができます。 ORDER BYでCASE文を使用すると、データのソート方法を制御できます。

SELECT * FROM `example` 
ORDER BY 
(CASE WHEN `alt_order` IS NULL THEN `my_order` ELSE (`my_order` + `alt_order`) END) 
関連する問題