具有最早行的SQL和列

具有最早行的SQL和列,sql,oracle,Sql,Oracle,我想从表中选择行,但不超过5000欧元的总和,从最旧的行开始。 从表中选择id、到货日期、公司名称、成本、地址,其中state='F'和sum(cost)=

我想从表中选择行,但不超过5000欧元的总和,从最旧的行开始。 从表中选择id、到货日期、公司名称、成本、地址,其中state='F'和sum(cost)=<5000订单(按到货日期); 如何在不超过5000欧元的成本下显示这些行?示例如下:

7;2003;soso;1000;Rue …;F
4;2004;jaja;3000;Rue …;F
6;2008;mama;500 ;Rue …;F
5;2009;lala;500 ;Rue …;F
表:

id  Date    Company Cost Address    STATE
1   2017    Toto    2000    Rue …   F
2   2019    vava    1000    Rue …   F
3   2008    tata    4000    Rue …   F
4   2004    jaja    3000    Rue …   F
5   2009    lala    500 Rue …   F
6   2008    mama    500 Rue …   F
7   2003    soso    1000    Rue …   F

提前感谢您的帮助。

您似乎想要累计金额:

select t.*
from (select t.*, sum(cost) over (order by date) as running_cost
      from t
      where state = 'F'
     ) t
where running_cost <= 5000;

您似乎想要一个累积的总和:

select t.*
from (select t.*, sum(cost) over (order by date) as running_cost
      from t
      where state = 'F'
     ) t
where running_cost <= 5000;
假设您的“期望输出”是正确的,那么问题很有趣。你不能简单地保持一个连续的总数,当总数超过5000时停止。相反,似乎按日期顺序排列行(如果日期相同,大概是按成本计算),那么依次考虑行,一次一行,或者将它们保留在输出中,或者丢弃它们,取决于添加该行是将选定的行的运行总数保持在5000以下,还是使其大于5000

这就是你最终选择拉拉(2009年起)的原因,即使你从2008年起放弃了塔塔。对吗

假设是这样的话,使用
match\u recognize
,这个问题有一个简单、优雅、高效的解决方案。这需要Oracle 12.1版或更高版本

WITH
子句不是解决方案的一部分(请删除它,并使用实际的表名和列名)。我包括它只是为了测试。另外:DATE是Oracle关键字,不应用作列名。我改用了日期(带尾随下划线)

假设您的“期望输出”是正确的,那么问题很有趣。你不能简单地保持一个连续的总数,当总数超过5000时停止。相反,似乎按日期顺序排列行(如果日期相同,大概是按成本计算),那么依次考虑行,一次一行,或者将它们保留在输出中,或者丢弃它们,取决于添加该行是将选定的行的运行总数保持在5000以下,还是使其大于5000

这就是你最终选择拉拉(2009年起)的原因,即使你从2008年起放弃了塔塔。对吗

假设是这样的话,使用
match\u recognize
,这个问题有一个简单、优雅、高效的解决方案。这需要Oracle 12.1版或更高版本

WITH
子句不是解决方案的一部分(请删除它,并使用实际的表名和列名)。我包括它只是为了测试。另外:DATE是Oracle关键字,不应用作列名。我改用了日期(带尾随下划线)


当您提出问题时,请始终包括您的Oracle版本(完整编号,例如11.2.0.4.0-使用
从v$version中选择banner
并查看它报告的内容)。例如,您的问题有一个优雅而高效的解决方案,使用
MATCH\u RECOGNIZE
,但该解决方案仅在12.1及更高版本中可用。还有一些问题需要解答。首先,你的“约会”实际上只是一年。在你的真实数据中是这样吗?然后:如果两行(或更多行)在同一年(具有相同的“日期”),您需要按什么顺序选择这些行?最后,一个大问题。在您的示例中,2008年有两行。在输出中,您没有选择“塔塔”,成本非常高;但你确实选择了2009年的那一行,这一行的总数仍然保持在5000以下。这是实际的要求,还是一个错误?Gordon Linoff给出了一个答案,认为这是一个错误,而不是期望的结果。当你问问题时,一定要包括你的Oracle版本(完整的数字,例如11.2.0.4.0-使用
从v$version中选择banner
,看看它报告了什么)。例如,您的问题有一个优雅而高效的解决方案,使用
MATCH\u RECOGNIZE
,但该解决方案仅在12.1及更高版本中可用。还有一些问题需要解答。首先,你的“约会”实际上只是一年。在你的真实数据中是这样吗?然后:如果两行(或更多行)在同一年(具有相同的“日期”),您需要按什么顺序选择这些行?最后,一个大问题。在您的示例中,2008年有两行。在输出中,您没有选择“塔塔”,成本非常高;但你确实选择了2009年的那一行,这一行的总数仍然保持在5000以下。这是实际的要求,还是一个错误?Gordon Linoff给出了一个答案,认为这是一个错误,而不是期望的结果。检查OP的“期望输出”,我们看到他选择了一行“日期”为2008。他没有选择2008年的其他行(这将使总数超过5000),但他选择了,然后包括2009年的行。如果这是期望的行为(而不仅仅是OP的一个错误——我请他澄清),那么这个解决方案将不会给出期望的结果。我看到你稍微修改了你的答案。它仍然没有解决我提出的问题(这不仅仅是不确定的顺序)。如果一行被丢弃,因为它使运行总数大于5000,但仍会考虑其他行,则问题没有基于分析和的简单解决方案。@mathguy。现在我明白你在说什么了。我错过了。你是对的。这是一个仓位打包问题,这并不是一个基于SQL的解决方案所能解决的。OP仍然需要确认我的读数是正确的。他也可能在“期望输出”方面犯了错误。话虽如此,问题并不是真正的箱子包装问题;在Oracle SQL中可以解决装箱问题(例如使用
match\u recognize
子句,但在较旧版本的Oracle中也可以解决装箱问题)。检查OP的“期望输出”,我们可以看到他选择了一行带有“date”2008。他也没有选择2008年的另一行(它将
with
  test_data (id, date_, company, cost, address, state) as (
    select 1, 2017, 'Toto', 2000, 'Rue ...', 'F' from dual union all
    select 2, 2019, 'vava', 1000, 'Rue ...', 'F' from dual union all
    select 3, 2008, 'tata', 4000, 'Rue ...', 'F' from dual union all
    select 4, 2004, 'jaja', 3000, 'Rue ...', 'F' from dual union all
    select 5, 2009, 'lala',  500, 'Rue ...', 'F' from dual union all
    select 6, 2008, 'mama',  500, 'Rue ...', 'F' from dual union all
    select 7, 2003, 'soso', 1000, 'Rue ...', 'F' from dual
  )
select id, date_, company, cost, address, state
from   test_data
match_recognize(
  order by date_, cost
  all rows per match
  pattern ( (a|{-b-})* )
  define  a as sum(a.cost) <= 5000
);

ID DATE_      COMPANY       COST ADDRESS STATE
-- ---------- ------- ---------- ------- -----
 7 2003       soso          1000 Rue ... F
 4 2004       jaja          3000 Rue ... F
 6 2008       mama           500 Rue ... F
 5 2009       lala           500 Rue ... F
select id, date_, company, cost, address, state
from   (
         select *
         from   (select t.*, row_number() over (order by date_, cost) as rn 
                 from test_data t)
         model
           dimension by (rn)
           measures  (id, date_, company, cost, address, state,
                      0 r_sum, 0 flag)
           rules automatic order (
             flag [any] = case when nvl(r_sum[cv() - 1], 0) + cost[cv()] <= 5000 
                               then 1 else 0 end,
             r_sum[any] = nvl(r_sum[cv() - 1], 0)
                          + case flag[cv()] when 1 then cost[cv()] else 0 end
           )
       )
where  flag = 1
;