Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle是否允许在分区上进行求和,但仅当它遵守某些条件时,否则使用滞后?_Sql_Oracle - Fatal编程技术网

Sql Oracle是否允许在分区上进行求和,但仅当它遵守某些条件时,否则使用滞后?

Sql Oracle是否允许在分区上进行求和,但仅当它遵守某些条件时,否则使用滞后?,sql,oracle,Sql,Oracle,因此,我的公司有一个应用程序,它具有特定的应用程序内货币。我们记录每一笔交易。 最近,我们发现有一个bug运行了几个星期,允许用户在某个地方消费货币,即使他们没有。当这种情况发生时,用户根本不会被收取费用:例如,用户有400万美元,并购买了价值1000万美元的东西。其余额将保持在4 现在我们需要找出谁滥用了它,他们的可用余额是多少 我想得到BUG_滥用和一厢情愿累积的专栏,反映非法交易和我们的用户在他们的应用内钱包中真正看到的金额,但我没有办法做到这一点 我想知道,如果结果超过0,我是否可以做一

因此,我的公司有一个应用程序,它具有特定的应用程序内货币。我们记录每一笔交易。 最近,我们发现有一个bug运行了几个星期,允许用户在某个地方消费货币,即使他们没有。当这种情况发生时,用户根本不会被收取费用:例如,用户有400万美元,并购买了价值1000万美元的东西。其余额将保持在4

现在我们需要找出谁滥用了它,他们的可用余额是多少

我想得到BUG_滥用和一厢情愿累积的专栏,反映非法交易和我们的用户在他们的应用内钱包中真正看到的金额,但我没有办法做到这一点

我想知道,如果结果超过0,我是否可以做一些类似于sumestrelas的事情,或者通过用户顺序、日期或类似的事情来获得一厢情愿的累积结果

我们正在使用oracle。非常感谢您的帮助

用户ID 活动日期 数量 方向 RK 中央机存储器 一厢情愿的 臭虫滥用 1. 02/01/2021 13:37:19,009000 -5 0 1. -5 0 1. 1. 08/01/2021 01:55:40,000000 40 1. 2. 35 40 0 1. 10/01/2021 10:45:41,000000 2. 1. 3. 37 42 0 1. 10/01/2021 10:45:58,000000 2. 1. 4. 39 44 0 1. 10/01/2021 13:47:37,456000 -5 0 5. 34 39 0 2. 13/01/2021 20:09:59,000000 2. 1. 1. 2. 2. 0 2. 16/01/2021 15:14:54,000000 -50 0 2. -48 2. 1. 2. 19/01/2021 02:02:59,730000 -5 0 3. -53 2. 1. 2. 23/01/2021 21:14:40,000000 3. 1. 4. -50 5. 0 2. 23/01/2021 21:14:50,000000 -5 0 5. -55 0 0
你可以试试看。这使用递归子查询分解递归WITH子句,因此它只适用于Oracle 11.2及更高版本

我使用您输入的用户ID、事件日期和金额列。我假设所有三列都被限制为非空,两个事件对于同一用户不能有完全相同的时间戳,并且金额对于购买和其他借记费用等为负数,对于存款或其他贷项为正数

输入数据如下所示:

select user_id, event_date, amount
from   sample_data
order  by user_id, event_date
;

USER_ID EVENT_DATE                    AMOUNT
------- ----------------------------- ------
      1 02/01/2021 13:37:19,009000000     -5
      1 08/01/2021 01:55:40,000000000     40
      1 10/01/2021 10:45:41,000000000      2
      1 10/01/2021 10:45:58,000000000      2
      1 10/01/2021 13:47:37,456000000     -5
      2 13/01/2021 20:09:59,000000000      2
      2 16/01/2021 15:14:54,000000000    -50
      2 19/01/2021 02:02:59,730000000     -5
      2 23/01/2021 21:14:40,000000000      3
      2 23/01/2021 21:14:50,000000000     -5
也许您的输入数据有其他列,如累积金额,我省略了它,因为它在问题或解决方案中不起作用。您显示一个RK列—我假设您将其计算为解决问题的一个步骤;我在下面的解决方案中重新创建了它

下面是使用递归查询recursive with子句可以执行的操作:

with
  p (user_id, event_date, amount, rk) as (
    select user_id, event_date, amount,
           row_number() over (partition by user_id order by event_date)
    from   sample_data
  )
, r (user_id, event_date, amount, rk, bug_flag, balance) as (
    select  user_id, event_date, amount, rk,
            case when amount < 0 then 'bug' end, greatest(amount, 0)
      from  p
      where rk = 1
    union all
    select  p.user_id, p.event_date, p.amount, p.rk, 
            case when p.amount + r.balance < 0 then 'bug' end,
            r.balance + case when r.balance + p.amount >= 0
                             then p.amount else 0 end
      from  p join r on p.user_id = r.user_id and p.rk = r.rk + 1
  )
select *
from   r
order  by user_id, event_date
;

为了产生您想要的结果,您可能需要按顺序处理行:为用户处理第一行后,您将计算第二行,然后计算第三行,依此类推

假设列RK已经计算并按顺序为每个用户排序,则可以执行以下操作:

with
n (user_id, event_date, amount, direction, rk, cum, wishful, bug_abuse) as (
  select t.*,
    greatest(amount, 0),
    case when amount < 0 then 1 else 0 end
  from t where rk = 1
 union all
  select
    t.user_id, t.event_date, t.amount, t.direction, t.rk, t.cum,
    greatest(n.wishful + t.amount, 0),
    case when n.wishful + t.amount < 0 then n.wishful 
                                       else n.wishful + t.amount
    end
  from n
  join t on t.user_id = n.user_id and t.rk = n.rk + 1
)
select *
from n
order by user_id, rk;

滥用意味着用户做了不该做的事情。你说这是一个bug,所以是由你的公司引起的。所以,不要称之为虐待;你的用户甚至没有利用这个漏洞。他们从中受益;他们也可能没有意识到这一点。毕竟,你是受此影响的人,甚至有几天你都没有注意到。试着理解你的数据,因为你认为自己这样做没有帮助。是负数购买,还是正数存款?方向列只是一个标志吗?0表示购买,1表示存款,因此是无用的信息复制?如果您将购买标记为错误滥用请注意,我反对上面的术语,您是否希望标记该交易,并将用户的钱包余额视为不允许该滥用购买,以便检查剩余交易?很可能这都可以在单个SQL查询中完成,但是你需要一个非常清晰的问题描述,就像我在之前的评论中写的那样,尤其是想要的输出。同样非常重要的是:您的Oracle版本是什么?因为不同版本的数据库引入了不同的高级功能。我同意,BUG_滥用这个词只是一个玩笑,因为它是一厢情愿的累积。有些人肯定滥用了它,不正当地购买了近4k次的东西。事实上,方向栏是我碰巧保存的无用信息的重复。我认为,帮助我更清晰地想象一些不可行的解决方案可能会很有用。我们正在使用oracle 12cHa!完全相同的解决方案。由于懒惰,我认为RK已经计算出来了。@TheImpler-差不多了。在递归分支中,您的解决方案具有greatestn.wiswish+t.amount,0,它似乎与列列表中的任何内容都不对应-相反,缺少bug_滥用的计算。嘿,非常感谢!我使用了您的解决方案,只是保留了rk,因为它确实是按用户划分的行数,按事件顺序,按日期asc。用户ID、事件日期和金额确实不是空的,用户不能有相同的事件日期。谢谢。这个解决方案与@mathguy发布的非常相似,但他的解决方案可以帮助我直接检查
我的交易被窃听了,所以我决定用他的。我真的很感谢你的帮助@如果mathguy的答案是正确的,那么接受它。
with
n (user_id, event_date, amount, direction, rk, cum, wishful, bug_abuse) as (
  select t.*,
    greatest(amount, 0),
    case when amount < 0 then 1 else 0 end
  from t where rk = 1
 union all
  select
    t.user_id, t.event_date, t.amount, t.direction, t.rk, t.cum,
    greatest(n.wishful + t.amount, 0),
    case when n.wishful + t.amount < 0 then n.wishful 
                                       else n.wishful + t.amount
    end
  from n
  join t on t.user_id = n.user_id and t.rk = n.rk + 1
)
select *
from n
order by user_id, rk;