0

いくつかの条件に基づいて、前の 2 つのレコードを取得するクエリがあります。これは正常に機能しますが、少なくとも 3 つのレコードがないとアイテムが見つかりません。そのため、以下のクエリを変更する必要がありますが、その方法がよくわかりません。

select t1.index
     , t1.date
     , t1.flag
     , t2.date
     , t2.flag
     , t3.date
     , t3.flag
from table t1
left outer join table t2
  on t2.index = t1.index
left outer join table t3
  on t3.index = t1.index
where t1.flag = '30'
  and t1.date >= to_date('05/08/2013','MM/DD/YYYY')
  and t2.date = (select max(t2a.date) from table t2a
                 where t2a.index = t1.index
                   and t2a.date < t1.date)
  and t3.date = (select max(t3a.date) from table t3a
                 where t3a.index = t1.index
                   and t3a.date < t2.date)

したがって、同じインデックス フィールドを持つレコードが少なくとも 3 つある限り、最新のレコード (t1) が検索され、次に最新のレコード (t2)、その次のレコード (t3) が検索されます。日にち。

私はラグ関数を使用していましたが、複雑なリンクと順序付けに基づいて、信頼できるものは得られませんでした (インデックスが 1 つのテーブルにあり、別のテーブルの日付が 3 番目のテーブルを介してリンクされているため、この例は馬鹿げています)。

基本的に、where ステートメントは、「既に見つかった日付よりも小さい基準に一致する最大日付を見つけるか、それ以上見つからない場合は問題なく、見つけたものを返す」ようにしたいと考えています。「または、それ以上何も見つからなかった場合」をどのようにコーディングしますか?

4

3 に答える 3

1

これは一つの方法です

select t1.index
     , t1.date
     , t1.flag
     , t2.date
     , t2.flag
     , t3.date
     , t3.flag
from table t1
left outer join table t2
  on t2.index = t1.index
  and t2.date = (select max(t2a.date) from table t2a
                 where t2a.index = t1.index
                   and t2a.date < t1.date)
left outer join table t3
  on t3.index = t1.index
  and t3.date = (select max(t3a.date) from table t3a
                 where t3a.index = t1.index
                   and t3a.date < t2.date)
where t1.flag = '30'
  and t1.date >= to_date('05/08/2013','MM/DD/YYYY')

もう1つは、T2とT3でand句をラップOR t2.date is nullし、t2リンクとT3.date is nullt3で使用することです

理由: 左結合は、T1 に存在する場合にのみ、T2 および t3 からのレコードを返します。これは最大値を見つけることができないため、結合またはwhere句でnullを評価することにより、「Null」を返します。ただし、これは、レコードが存在する場合、「日付」フィールドが常に入力されていることを前提としています。

于 2013-05-29T23:02:36.717 に答える
0

ここでの問題は、外部結合を使用して t2 と t3 に結合しているが、WHERE句に条件を入れていることです。これらの条件をJOIN句に移動すると、問題が解決するはずです。

別の方法として、分析関数を使用してこのクエリを試し、クエリMAXから関数を削除することもできます。これにより、ロジックが少し簡素化され、パフォーマンスも向上する可能性があります。

with my_table as (
  select 
    index, 
    date, 
    flag,
    row_number() over (partition by index order by date desc) as rown
  from table
)
select t1.index
     , t1.date
     , t1.flag
     , t2.date
     , t2.flag
     , t3.date
     , t3.flag
from table t1
left outer join table t2
  on (t2.index = t1.index and t2.rown = t1.rown + 1)
left outer join table t2
  on (t3.index = t2.index and t3.rown = t2.rown + 1)
where t1.flag = '30'
  and t1.date >= to_date('05/08/2013','MM/DD/YYYY')
于 2013-05-29T23:09:56.663 に答える