0

我有一个查询,它根据一些资格获取前两条记录。这很好用,但如果没有至少三个记录,它就不会找到项目。所以,我需要在下面修改我的查询,但我不太确定如何。

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)

因此,只要有至少三个具有相同索引字段的记录,它就会找到最近的记录(t1),然后找到下一个最近的记录(t2),然后是之后的记录(t3),排序为日期。

根据我复杂的链接和排序,我正在使用滞后函数并且没有得到任何可靠的东西(这个例子被简化了,因为索引在一个表中,另外一个表中的日期通过第三个表链接。)

从本质上讲,我希望 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')

另一种方法是将您的 and 子句包装在 T2 和 T3 上,并OR t2.date is null在 t2 链接和T3.date is nullt3 上使用

至于为什么:左连接仅在 T1 中存在时才返回来自 T2 和 t3 的记录。哪个不会找到最大值,因此它通过评估连接上的 null 或它应该工作的 where 子句来返回“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 回答
0

您可能想要进入 LEAD 和 LAG 分析函数。它们的工作方式与您的问题中所述的稍有不同,返回(对于 LEAD)“下一个”和“下一个 + 1”值作为同一行的一部分而不是单独的行,但也许它们会被证明是有用的。示例小提琴在这里

分享和享受。

于 2013-05-30T02:34:11.203 回答