Oracle 11g - 什么可以替代 Fetch next 1 rows only

Oracle 11g - What can replace Fetch next 1 rows only

这是我的table。 (Table 1)

这是预期的结果。 (Table 2)

这就是我现在得到的。 (Table 3)

比如我要40的数量。结果应为 table 2 但我得到 table 3。Running_total 必须等于或大于请求的数量。

select  id, quantity, running_total  from 
( 
select id, quantity, sum(quantity) over (partition by id ) running_total from table 
) 
where running_total <= 40;

这是我的代码。 经过研究,我发现Offset和Fetch可能会在table 2中获取结果,但我使用的是Oracle 11g。 (11g不支持offset和fetch)

select  id, quantity, running_total  from 
( 
select id, quantity, sum(quantity) over (partition by id ) running_total from table 
) 
where running_total <= 40
Offset 0 rows fetch next 1 rows only;

任何东西都可以代替仅获取下 1 行或其他任何方式来获取结果? 谢谢。

如果我现在理解正确,你想显示所有行,直到你至少达到 40。使用

+------------+----------+---------+
| product_id | quantity | sortkey |
+------------+----------+---------+
|          1 |       10 |       1 |
|          1 |       20 |       2 |
|          1 |       30 |       3 |
|          1 |       40 |       4 |
|          1 |       50 |       5 |
|          2 |       20 |       1 |
|          2 |       20 |       2 |
|          2 |       20 |       3 |
+------------+----------+---------+

你会想展示

+------------+----------+---------+-------+
| product_id | quantity | sortkey | total |
+------------+----------+---------+-------+
|          1 |       10 |       1 |    10 |
|          1 |       20 |       2 |    30 |
|          1 |       30 |       3 |    60 |
|          2 |       20 |       1 |    20 |
|          2 |       20 |       2 |    40 |
+------------+----------+---------+-------+

因为 60 您最终达到了产品 #1 的 40,而对于产品 #2 您恰好达到了 40。

这很难,因为您不能将结果限制为 <= 40,因为您可能还需要第一个值 > 40。 (对于产品 #1,您可以,对于产品 #2,您不需要。)

我的方法是:显示总计 < 40 的所有行和总计 >= 40 的第一行。

select product_id, quantity, sortkey, total
from
(
  select
    product_id, quantity, sortkey, total,
    min(case when total >= 40 then total end) over (partition by product_id) as reached
  from
  (
    select
      product_id, quantity, sortkey,
      sum(quantity) over (partition by product_id order by sortkey) as total
    from mytable
  )
)
where total < 40 or total = reached
order by product_id, sortkey;

从您比较的 运行 总数中减去数量:

select id,
       quantity,
       running_total
from   ( 
  select id,
         quantity,
         sum(quantity) over (
           partition by id
           ORDER BY dt
         ) AS running_total
  from   table_name
) 
where running_total - quantity < 40;

(注意:在 SQL 中,行是无序的,因此您需要提供一些对行进行排序的方法;我添加了一个 DT 列来提供这种排序。 )

其中,对于示例数据:

CREATE TABLE table_name ( id, quantity, dt ) AS
SELECT 1, 10, DATE '2020-01-01' FROM DUAL UNION ALL
SELECT 1, 20, DATE '2020-01-02' FROM DUAL UNION ALL
SELECT 1,  5, DATE '2020-01-03' FROM DUAL UNION ALL
SELECT 1,  1, DATE '2020-01-04' FROM DUAL UNION ALL
SELECT 1,  8, DATE '2020-01-05' FROM DUAL UNION ALL
SELECT 1, 30, DATE '2020-01-06' FROM DUAL UNION ALL
SELECT 2, 20, DATE '2020-01-01' FROM DUAL UNION ALL
SELECT 2, 20, DATE '2020-01-02' FROM DUAL UNION ALL
SELECT 2, 20, DATE '2020-01-03' FROM DUAL;

输出:

ID | QUANTITY | RUNNING_TOTAL
-: | -------: | ------------:
 1 |       10 |            10
 1 |       20 |            30
 1 |        5 |            35
 1 |        1 |            36
 1 |        8 |            44
 2 |       20 |            20
 2 |       20 |            40

db<>fiddle here