【问题标题】:Oracle get sequence or rownum plus previous rowsOracle获取序列或rownum加上前几行
【发布时间】:2013-07-17 01:31:35
【问题描述】:

我可以得到一个序列 - using rownum() OVER (order by <field>) - 或只是 rownum(见下文),但我正在努力获得一个特定 rownum/seq 和“前一个”两行。

该表是日期列表,并且每一天的日期对应于每月的日期 - 不一定 一定是当前月份。 (由于是星期几,下个月的周四/周五仍可能“在”上个月的存储桶中)。

我的目标是将表连接到自身,获取今天的日期,然后获取相应的每月日期。我认为我遇到的问题是在外部查询的 WHERE 子句中,我不能这样做: where rnum between (DDate is not NULL) and ((DDate is not NULL) -2) 或类似的东西。

总之——

  1. 获取DDate不为null的rownum(只有一个 行,因为它基于 SYSDATE)
  2. 从前两行获取 MDate 值(这是我的 最终目标,两个月前的 MDate - 我需要的唯一值)
select t2.* from ( select rownum rnum, t1.* from ( select distinct to_char(r.MONTHLY, 'YYYY-MM-DD') as MDate, to_char(l.DAILY, 'YYYY-MM-DD') as DDate from Z_DATES l right outer join Z_DATES r on to_char(l.MONTHLY, 'YYYY-MM-DD') = to_char(r.MONTHLY, 'YYYY-MM-DD') and to_char(l.DAILY, 'YYYY-MM-DD') = to_char(SYSDATE, 'YYYY-MM-DD') order by 1 ) t1 order by rnum ) t2 -- where DDate is not NULL -- where rnum between 11 and 13 RNUM MDATE DDate 11 2013-04-29 12 2013-05-27 13 2013-07-01 2013-07-16

【问题讨论】:

    标签: oracle rownum


    【解决方案1】:

    使用 t1 你现在的方式,这应该可以工作:

    select LAG(mdate, 2) over (order by mdate)
    from (
        ...
    ) t1
    where ddate is not null
    

    如果您重新考虑 LAG 功能的问题,我认为之后可以进一步清理(甚至可能不需要自加入)。

    【讨论】:

    • 感谢 Wumpus 的回复。我确实通过 LAG 获得了一些有效记录(我需要继续阅读)。
    【解决方案2】:

    我认为这符合您的描述:

    select to_char(monthly, 'YYYY-MM-DD') as mdate,
      to_char(daily, 'YYYY-MM-DD') as ddate
    from (
      select distinct monthly,
        max(case when daily = trunc(sysdate) then daily end)
          over (partition by monthly) as daily,
        dense_rank() over (order by monthly desc) as rn
      from z_dates
      where daily <= trunc(sysdate)
    )
    where rn <= 3
    order by monthly;
    

    内部选择获取当前伪月的今天日期,否则为 null,并为每个月分配一个排名。然后外部选择将其限制为三行。如果您只想要两个月前的值(这有点不清楚),那么只需使用 = 3 而不是 &lt;= 3。过滤器where daily &lt;= trunc(sysdate) 是为了以防万一有任何未来的日期,这从您描述表格的方式来看是合理的,但无论如何都不会造成任何伤害。

    SQL Fiddle.

    如果您只想要两个月前的日期,那就更简单了,您无需执行max() 部分或获取ddate

    select to_char(monthly, 'YYYY-MM-DD') as mdate
    from (
      select distinct monthly,
        dense_rank() over (order by monthly desc) as rn
      from z_dates
      where daily <= trunc(sysdate)
    )
    where rn = 3;
    

    SQL Fiddle.

    【讨论】:

    • Alex - 感谢您的帮助 - 以及更简单的查询与我的自我加入。更改为 =3 正是我们所需要的。
    • @user1628169 - 没问题。如果你只想要那个单一的值2013-04-29,那么我添加了一个只得到那个的精简版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多