2012-05-07 4 views
0

ID、ParentID、タイムスタンプ、値の4つの列を持つテーブルがあるとします。 ParentIDは値の意味を変更します。私はParentID = 1で、TimestampがParentID = 2のテーブル内のアイテムのタイムスタンプ内にあり、ParentID.Value> 10のアイテムのタイムスタンプ内にあるこのテーブルからすべてのエントリを返す必要があります。日付範囲のリミッタを使用して自己結合のクエリを決定するのに役立つ

たとえば、ここいくつかのデータです:

ID ParentID TimeStamp Value 
1  1   51   1 
2  2   52   11 
3  1   53   2 
4  1   54   3 
5  2   55   9 
6  1   56   4 
7  2   57   12 
8  1   58   5 
9  1   53.5   1 

私はこのクエリは、SQLまたはLINQでどのように見えるかIDが3、4、8、および9で私にそれらの行を返すクエリが必要?自分で参加することは許されていますか?ここでそのアプローチを使用しますか?私はタイムスタンプの範囲を決定する方法に立ち往生しています。私はSqliteを使用しています。ありがとう。

明確化:私はこれは珍しい問題である= 2

+1

値56は、ParentID = 2のテーブル内のアイテムのタイムスタンプ内にあり、ParentID.Valueが10以上のアイテムであるため、ID = 6はこの基準に従って結果セットに含める必要があります。 – gcbenison

+0

@gcbenison:一方、 'ID = 8'の行は条件を満たしていないようです。私の推測は、OPは、3,4,8、および9の代わりに、3,4,6、および9と言うことを意味しています。 –

+0

gcbenison&Andriy M、あなたはその質問を誤解しました。明らかに、私はそれを明確にするために苦労していたので、心配はしませんでした... ParentID == 2の前の行が10より大きくないため、「6」は有効な答えではありません。 – Brannon

答えて

3

値がgreatherある場合、この醜いと遅いクエリはそれぞれのParentID = 1行十分のParentID = 2行をチェックするごとに見つけ10より大きい。そうならば、行を出力します

select * 
    from table1 
where table1.parentid = 1 
    and exists 
     (
     select null 
     -- Isolate previous ParentID = 2 row 
     from 
     (
      select p2.value 
      from table1 p2 
      where p2.timestamp < table1.timestamp 
       and p2.parentid = 2 
       -- Only one needed 
      order by p2.timestamp desc 
      limit 1 
     ) p2_1 
     -- Make sure it has appropriate value 
     where p2_1.value > 10 
     ) 

これは一度だけスキーマの変更後にテーブルの更新のコンテキストで実行されている価値があります。あなたは(つまり、階層的に記録を接続)本当にのParentIDするのParentIDを変更することができれば、クエリは簡単になる:

select Child.* 
    from table1 Child 
inner join table1 Parent 
    on child.ParentID = Parent.ID 
where Parent.Value > 10 

のParentIDは、当然のことながら、挿入し、関与いくつかの数学が存在することになる前に発見されなければならなかったでしょうビジネスモデルでアウトオブオーダーのインサートが可能な場合。シンプルなタイムスタンプの追加だけが必要な場合は、これが最も簡単な解決策になります。

このクエリのSql Fiddleライブテストがあります。

0

のParentIDで(タイムスタンプによって判断)最新の行によってフィルタリングします。これが宿題の場合は、そのようにタグ付けする必要があります。

次のクエリは、あなたが記述何をしているようだ:

select p1.* 
from (select * 
     from table t 
     where ParentId = 1 
    ) p1 cross join 
    (select min(TimeStamp) as minTS, max(TimeStamp) as maxTS 
     from table t 
     where ParentId = 2 and value > 10 
    ) p2 
where t.TimeStamp between minTS and maxTS 

そして、あなたの質問への答えは「イエス」で、すべてのSQLデータベースは、自己加入をサポート。 LINQで

+0

これは宿題ではありません。幸いにも、私は数年前にそれをラップしました!提案されたクエリで、ParentID列のスイッチ効果(より良い用語が不足しているため)をどのように維持していますか?言い換えれば、ParentID 2のmin/maxの間のすべてを望んでいません。 – Brannon

+0

元のデータには、1行につきタイムスタンプが1つしかありません。私は、「アイテムのタイムスタンプ内で...」を「範囲内」と解釈しました。私は他の人がこのようにあなたの声明を解釈したと思います。 –

0

それはこれが動作するはずつのクエリである必要はない場合:

var values = table.Where(a => a.parentid == 2 
          && a.value > 10) 
        .Select(a.timestamp); 

var min = values.Min(); 
var max = values.Max(); 

var result = table.Where(a => a.parentid == 1 
          && timestamp >= min 
          && timestamp <= max) 
        .Select(a => a.value); 
+0

ジョアンナ、私は答えが間違っていることを恐れています。 Min/Maxは、データを除外したい場所に穴がある可能性があるため、機能しません。 – Brannon

+0

@Brannon - 申し訳ありませんが、あなたが何を意味するのか分かりません。私がデータの隙間を言及していないことを知っている限り、私はそれを魔法のように知っているとは思わないでください。あなたから-1投票カムなら、私はもう一度お手伝いしないように覚えています。 –

関連する問題