【问题标题】:SQL Oracle Specify start point using ROW_NUMBER()SQL Oracle 使用 ROW_NUMBER() 指定起点
【发布时间】:2017-09-20 11:58:52
【问题描述】:

我得到了这个代码:

ROW_NUMBER() OVER (partition by ID ORDER BY ID DESC, year DESC, month DESC, day DESC) rank

我想确定开始排名的确切年份、月份和日期。 在那种情况下我应该把这个条件放在哪里?

提前谢谢你!

------------------------------------------ - - - - -编辑: - - - - - - - - - - - - - - - - - - - - -------------

我将详细说明我的情况,以便向您展示我到底想要什么。

让我们使用这个示例表并假设每个日期都有值。

| Year | Month | Day | ID        | Rank       |
|------|-------|-----|-----------|------------|
| 2017 | 9     | 14  | 9555      | 1          |
| 2017 | 9     | 13  | 9555      | 2          |
| 2017 | 9     | 12  | 9555      | 3          |
| 2017 | 9     | 11  | 9555      | 4          |
| 2017 | 9     | 14  | 3000      | 1          |
| 2017 | 9     | 13  | 3000      | 2          |
| 2017 | 9     | 12  | 3000      | 3          |
| 2017 | 9     | 11  | 3000      | 4          |

这个表是你可以使用下面的代码得到的:

Select *
From (Select Year,
             Month,
             Day,
             ID,
             ROW_NUMBER() OVER (partition by ID ORDER BY ID DESC, Year DESC, Month DESC, Day DESC) rank
      From table1
      Where (Condition)
      )
Where Rank < 5;   

我们的示例表的条件是最近的行来自 2017 年 9 月 14 日。 我的问题是如何获得 2017 年 9 月 13 日的最后 4 行?

【问题讨论】:

  • 所以您希望该日期从 1 开始,而之前的所有其他日期都为空?
  • 不知道你想问什么——也许如果你添加了样本数据预期结果,它会更清楚。但是,我会注意到,在 partition byorder by 子句中具有相同的列通常没有任何意义(提示:如果您按特定列进行分区,那么每个分区中的所有行都具有,根据定义,该列中的相同值)
  • @xQbert,Damien_The_Unbeliever。我编辑了我的问题,所以你可以理解我在问什么。
  • 你不会更新 where 条件(内部查询)来规定where to_date(Year||lpad(Month,2,0)||lpad(Day,2,0),'YYYYMMDD') &lt;= to_date('13/09/2017','DD/MM/YYYY') 吗?转换为日期,因此我不必处理月初边缘情况或闰年等。我只是让日期数据类型为我处理。
  • @xQbert 谢谢,它可以工作,就像上面提到的解决方案 MT0。

标签: sql oracle row-number


【解决方案1】:

使用CASE 声明:

CASE
  WHEN TO_DATE(
         TO_CHAR( year, 'FM0000' )
         || '-' || TO_CHAR( month, 'FM00' )
         || '-' || TO_CHAR( day, 'FM00' ),
         'YYYY-MM-DD'
       ) > DATE '2017-01-01' -- Your start date
  THEN ROW_NUMBER() OVER (partition by ID
                          ORDER BY ID DESC, year DESC, month DESC, day DESC)
END AS rank

但是为什么您将日期存储在 yearmonthday 列中,而不仅仅是一个 DATE 数据类型?

更新

我怎样才能得到 2017 年 9 月 13 日的最后 4 行

这将使您的排名仅应用于 2017 年 9 月 13 日或之前的行:

SELECT *
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER (partition by ID 
                            ORDER BY ID DESC, Year DESC, Month DESC, Day DESC) rank
  FROM   table1 t
  WHERE  TO_DATE(
           TO_CHAR( year, 'FM0000' )
           || '-' || TO_CHAR( month, 'FM00' )
           || '-' || TO_CHAR( day, 'FM00' ),
           'YYYY-MM-DD'
         ) <= DATE '2017-09-13'
)
WHERE rank < 5

【讨论】:

  • 感谢 MT0,但我认为这个解决方案不是我所找到的。您可以查看我已编辑的原始问题。我希望这个日期条件影响整个查询,而不仅仅是 row_number() 字段。
  • @Roy90 已更新。
  • 感谢 MT0,现在它正在按预期工作。我将尝试在更新时使用此 Select。让我们看看一切是否顺利。
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 2013-02-19
  • 2018-09-16
  • 2012-04-13
  • 1970-01-01
  • 2013-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多