2017-09-26 5 views
0

私はDATEの2つのペアを持つテーブルを持っています。私はこれらの日付の時間に基づいて結果を注文したい。Oracle OR MySQL - NULL値に応じて異なるcritereaを持つカスタムORDER

 | start1 | end1 | start2 | end2 
row 1 | 4:00 | 5:00 | 5:00 | 6:00 
row 2 | 4:30 | 5:00 | NULL | NULL 
row 3 | NULL | NULL | 5:30 | 6:00 
row 4 | 5:00 | 6:00 | 6:00 | 7:00 
  • 2つの行があります:このように、(START2> START1、END2> END1とSTART2> = END1行が間隔の両方を有する)各行が、日付の少なくともつのペアを持っています両方のペアは、start1で比較する必要があります。 START1が

  • 一列は一組(任意)を有し、他方は両方の対を有する場合、それらは比較されるべきであるがSTART2と比較されるべき、一列のみPAIR1を有し、他は唯一PAIR2を有する

  • (start1からstart1またはstart2からstart2までの)ペアによって、最初の行が持っています。たとえば、最初の行にstart2とend2のみがあり、2番目の行にstart1、end1、start2とend2がある場合、これらの2つの行はstart2だけ比較されます(2番目の行からのstart1は無視する必要があります)

どうすれば実現できますか?


EDIT

私は簡単にC#でそれを行うことができますが、私は、データベースにこの操作を行う必要があります。それはC#で動作するべきかのコードの下:

static void Main(string[] args) 
{ 
    ... 
    intervals.Sort(new IntervalComparer()); 
} 
public class IntervalComparer : IComparer<Interval> 
{ 
    public int Compare(Interval quadro1, Interval quadro2) 
    { 
     int result = 0; 
     if (quadro1.start1 != null && quadro2.start1 != null) 
      result = quadro1.start1.Value.CompareTo(quadro2.start1.Value); 
     else if (quadro1.start2 != null && quadro2.start2 != null) 
      result = quadro1.start2.Value.CompareTo(quadro2.start2.Value); 
     else if (quadro1.start1 != null) 
      result = quadro1.start1.Value.CompareTo(quadro2.start2.Value); 
     else 
      result = quadro1.start2.Value.CompareTo(quadro2.start1.Value); 
     return result; 
    } 
} 
+1

Oracle®DatabaseまたはOracle®MySQL? – Alfabravo

+0

私はそれらの両方でやってみたいですが、どんな助けも歓迎です – romerotg

+0

Oracle NVLやORDER BYで... NULLS LAST/FIRSTはあなたの友人です –

答えて

1

あなたのロジックに欠陥があります。あなたのロジックを使用して、真のだろう

| start1 | start2 
a | 4:00 | 7:00 
b | 5:00 | NULL 
c | NULL | 6:00 

以下、そのデータの場合:次の例を考えてみましょう

a < b (a.start1 = 4:00 < b.start1 = 5:00) 
b < c (b.start1 = 5:00 < c.start2 = 6:00) 
c < a (c.start2 = 6:00 < a.start2 = 7:00) 

こうしてa < b < c < aが「真」もあります。しかし、意味のある注文をしたい場合は、<オペレーターは推移的でなければなりません。つまり、a < bがTRUEでb < cがTRUEの場合は、a < cもTRUEになります。しかし、そうではありません。

したがって、3行を[a, b, c]または[b, c, a]または[c, a, b]と並べることができます。私にとっては意味がありません。

SQLソリューションが必要な場合は、ロジックを再定義する必要があります。推定(平均)差(AVG(start2 - start1))を使用してNULLを埋めることをお勧めします。私の例では、平均差は3時間です。したがってb.start2b.start1 + 3 hours = 8:00に置き換えられます。 c.start1c.start2 - 3 hours = 3:00に置き換えられます。これで、見積もり値で注文することができます。

MySQLの例:あなたはもちろん、ORDER BY句での推定式を使用することができます

select t.* 
    , d.avg_diff 
    , coalesce(time_to_sec(t.start1), time_to_sec(t.start2) - d.avg_diff) as estimated1 
    , coalesce(time_to_sec(t.start2), time_to_sec(t.start1) + d.avg_diff) as estimated2 
from my_table t 
cross join (
    select avg(time_to_sec(start2) - time_to_sec(start1)) 
     as avg_diff 
    from my_table 
) d 
order by estimated1, estimated2; 

select t.* 
from my_table t 
cross join (
    select avg(time_to_sec(start2) - time_to_sec(start1)) 
     as avg_diff 
    from my_table 
) d 
order by 
    coalesce(time_to_sec(t.start1), time_to_sec(t.start2) - d.avg_diff), 
    coalesce(time_to_sec(t.start2), time_to_sec(t.start1) + d.avg_diff); 

デモ:http://rextester.com/AMJIDT94457

:元のデータと http://rextester.com/HHLT51865

デモ

+0

私は問題に目を向けるので、私は間違ったアプローチをとっているようです。また、[NULL、NULL、5:00、6:00]のような既存のものに基づいてNULL値をミラーリングしようとすると、[4:00、5:00、5:00、6:00]として扱われます。どうもありがとう!クールダウンが私に許したら、賞金をあげます。 – romerotg

0

IF functionを使用してみてください、それはの線に沿って何かする必要があります:

あなたの全体の論理は、上記のクエリのように簡略化することができ
SELECT if(start1 not is null, TIME(start1), TIME(start2)) AS sortable_value 
FROM your_table ORDER by sortable_value 

。 start1がnullでない場合は基本的にはになります。それ以外の場合はstart2の時刻で並べ替えます

私が何かを間違って解釈した場合、あなたは時間の代わりに別のIFを追加することができますが(then枝のと同じです)(START1)またはその代わりのTIME(START2)(else branchに相当)。

+0

少し質問を編集しました。その答えでは、「1つの行に1つのペア(any)があり、もう一方のペアに両方のペアがある場合は、最初の行(start1〜start1またはstart2〜start2)のペアで比較する必要があります。 。あなたのコードでは、ある行にstart1とstart2があり、もう一方の行にstart2のみがあった場合、start1と2を比較します.1つのクエリでこれを達成できるかどうかはわかりません。私はちょっと失われています – romerotg

+0

最初の行にある*ペアの意味は?*?現在のところソートがないので、この時点で**最初の行**はありません。 –

+0

つまり、OP上の行の場合、結果(ソート前)は(start1、start1、start2、start1)になり、ソートはそれらの値を使用して行われます。しかし、私が望む振る舞いは、「行3」はstart2の値を[行1、開始2]、[行2、開始1]、[行3、開始2]と比較する必要があるということです。 – romerotg

関連する問題