从另一张桌子订购最多或最少

时间:2010-05-05 20:01:24

标签: java sql oracle

我有一个由唯一ID和一些其他属性组成的表。它持有“时间表”。然后我有另一个表,其中包含每个计划已经或将“触发”的所有时间的列表。这不是确切的架构,但它很接近:

create table schedule (
   id varchar(40) primary key,
   attr1 int,
   attr2 varchar(20)
);

create table schedule_times (
   id varchar(40) foreign key schedule(id),
   fire_date date
);

我想在Java中查询调度表,获取属性以及下一个和之前的fire_dates,有时会对其中一个属性进行排序,但有时会在之前的fire_date或下一个fire_date中进行排序。通过属性排序很容易,我只是在构建我准备好的语句时将“order by”粘贴到字符串中。我甚至不确定如何在单个查询中选择最后一个fire_date和下一个fire_date - 我知道我可以通过执行

找到给定id的下一个fire_date
SELECT   min(fire_date)
FROM     schedule_times
WHERE    id = ? AND
         fire_date > sysdate;

以及使用max()fire_date < sysdate的上一次fire_date的类似内容。我只是简单地说明了如何将其合并到一个选项中,这样我就可以一次性获得下一个和之前的fire_date,以及如何按这些属性中的任何一个进行排序。

3 个答案:

答案 0 :(得分:4)

您可以使用Left Join中的两个子查询来执行此操作 如果没有下一个/上一个时间表,这样做的好处就是为fire_dates返回NULL

Select id, attr1, attr2, next_fire_date, previous_fire_date
From schedule s
Left Join ( Select id, Min(fire_date) As next_fire_date
            From schedule_times st
            Where st.fire_date > Sysdate
            Group By id ) n
    On ( n.id = s.id )
Left Join ( Select id, Max(fire_date) As previous_fire_date
            From schedule_times st
            Where st.fire_date < Sysdate
            Group By id ) p
    On ( p.id = s.id )

然后,您可以在ORDER BYnext_fire_date上添加previous_fire_date


如果性能很重要,请在schedule_times( id, fire_date )上创建复合索引,这将允许子查询只读取此索引。

答案 1 :(得分:3)

尝试这样的事情:

select schedule.*,
(
    select max(si.fire_date) from schedule_times si where si.id = schedule.id and si.fire_date < sysdate
) as prevfire,

(
    select min(si.fire_date) from schedule_times si where si.id = schedule.id and si.fire_date > sysdate
) as nextfire
from schedule
where id = ?
order by attr1

答案 2 :(得分:0)

将查询修改为

SELECT 区别 S.ID,ATTR1,ATTR2, LEAD(FIRE_DATE,1, SYSDATE )OVER(由S.ID分配的S.ID ORDER)NEXT_FIRE_DATE, LAG(FIRE_DATE,1, SYADATE )OVER(由S.ID分配的S.ID ORDER)PREV_FIRE_DATE 来自SCHEDULE S,SCHEDULE_TIMES ST,其中ST.ID = S.ID;

这是简单的查询。你可以尝试这个。

LEAD能够计算下一行(将在当前行之后的行)上的表达式,并将值返回到当前行。 LEAD的一般语法如下所示:

LEAD(sql_expr,offset,default)OVER(analytic_clause)

  1. sql_expr 是从前导行计算的表达式。
  2. 偏移量是相对于当前行的前导行的索引 行。 offset是一个正整数 默认为1。
  3. 默认是偏移量指向行时要返回的值 在分区范围之外。
  4. LAG的语法类似,只是LAG的偏移量会进入前一行。