使用 Oracle SQL 进行带有一些逻辑网络的汇总查询

2024-04-07

我有一个如下表“AuctionResults”

Auction  Action    Shares  ProfitperShare   
------------------------------------------- 
Round1   BUY        6      200    
Round2   BUY        5      100   
Round2   SELL      -2      50   
Round3   SELL      -5      80

现在,我需要按照“净值先到先得”的原则,在后续几轮中扣除卖出后,对每次拍卖的买入结果进行汇总

因此,在第 1 轮中,我买入 6 股,然后在第 2 轮中卖出 2 股,在第 3 轮中卖出“4”股,总净利润为 6 * 200-2 * 50-4 * 80 = 780

在第 2 轮中,我购买了 5 股,并在第 3 轮中卖出了“1”(因为之前的“4”属于第 1 轮),净利润为 5 * 100-1 * 80 = 420

...所以结果输出应该如下所示:

Auction   NetProfit
------------------
Round1    780    
Round2    420   

我们可以仅使用 Oracle SQL(10g) 而不是 PL-SQL 来完成此操作吗

提前致谢


我知道这是一个老问题,对原始海报没有用,但我想尝试一下,因为这是一个有趣的问题。我没有对其进行足够的测试,所以我认为这仍然需要纠正和调整。但我相信这种做法是合理的。我不建议在产品中使用这样的查询,因为它很难维护或理解(而且我不相信这真的是可扩展的)。创建一些替代数据结构会更好。话虽如此,这就是我在 Postgresql 9.1 中运行的:

    WITH x AS (
        SELECT round, action
              ,ABS(shares) AS shares
              ,profitpershare
              ,COALESCE( SUM(shares) OVER(ORDER BY round, action
                                          ROWS BETWEEN UNBOUNDED PRECEDING 
                                                   AND 1 PRECEDING)
                        , 0) AS previous_net_shares
              ,COALESCE( ABS( SUM(CASE WHEN action = 'SELL' THEN shares ELSE 0 END)
                            OVER(ORDER BY round, action
                                     ROWS BETWEEN UNBOUNDED PRECEDING 
                                              AND 1 PRECEDING) ), 0 ) AS previous_sells
          FROM AuctionResults
          ORDER BY 1,2
    )

    SELECT round, shares * profitpershare - deduction AS net
      FROM (

           SELECT buy.round, buy.shares, buy.profitpershare
                 ,SUM( LEAST( LEAST( sell.shares, GREATEST(buy.shares - (sell.previous_sells - buy.previous_sells), 0)
                                    ,GREATEST(sell.shares + (sell.previous_sells - buy.previous_sells) - buy.previous_net_shares, 0)
                                   )
                             ) * sell.profitpershare ) AS deduction
             FROM x buy
                 ,x sell
             WHERE sell.round > buy.round
               AND buy.action = 'BUY'
               AND sell.action = 'SELL'
             GROUP BY buy.round, buy.shares, buy.profitpershare

           ) AS y

结果:

     round | net
    -------+-----
         1 | 780
         2 | 420
    (2 rows)

为了将其分解为几部分,我从这个数据集开始:

    CREATE TABLE AuctionResults( round int, action varchar(4), shares int, profitpershare int);

    INSERT INTO AuctionResults VALUES(1, 'BUY', 6, 200);
    INSERT INTO AuctionResults VALUES(2, 'BUY', 5, 100);
    INSERT INTO AuctionResults VALUES(2, 'SELL',-2, 50);
    INSERT INTO AuctionResults VALUES(3, 'SELL',-5, 80);
    INSERT INTO AuctionResults VALUES(4, 'SELL', -4, 150);  

    select * from auctionresults;

     round | action | shares | profitpershare
    -------+--------+--------+----------------
         1 | BUY    |      6 |            200
         2 | BUY    |      5 |            100
         2 | SELL   |     -2 |             50
         3 | SELL   |     -5 |             80
         4 | SELL   |     -4 |            150
    (5 rows)

“WITH”子句中的查询将一些运行总计添加到表中。

  • “previous_net_shares”表示在当前记录之前有多少股可供出售。这也告诉我在开始将其分配给“买入”之前需要跳过多少“卖出”股票。
  • “previous_sells”是遇到的“SELL”股票数量的运行计数,因此两个“previous_sells”之间的差异表示当时使用的“SELL”股票数量。

     round | action | shares | profitpershare | previous_net_shares | previous_sells
    -------+--------+--------+----------------+---------------------+----------------
         1 | BUY    |      6 |            200 |                   0 |              0
         2 | BUY    |      5 |            100 |                   6 |              0
         2 | SELL   |      2 |             50 |                  11 |              0
         3 | SELL   |      5 |             80 |                   9 |              2
         4 | SELL   |      4 |            150 |                   4 |              7
    (5 rows)
    

通过此表,我们可以进行自连接,其中每个“买入”记录都与每个未来的“卖出”记录相关联。结果如下:

    SELECT buy.round, buy.shares, buy.profitpershare
          ,sell.round AS sellRound, sell.shares AS sellShares, sell.profitpershare AS sellProfitpershare
      FROM x buy
          ,x sell
      WHERE sell.round > buy.round
        AND buy.action = 'BUY'
        AND sell.action = 'SELL'

     round | shares | profitpershare | sellround | sellshares | sellprofitpershare
    -------+--------+----------------+-----------+------------+--------------------
         1 |      6 |            200 |         2 |          2 |                 50
         1 |      6 |            200 |         3 |          5 |                 80
         1 |      6 |            200 |         4 |          4 |                150
         2 |      5 |            100 |         3 |          5 |                 80
         2 |      5 |            100 |         4 |          4 |                150
    (5 rows)

然后是疯狂的部分,试图计算订单中可出售的股票数量与尚未出售的股票数量。以下是一些有助于遵循这一点的注释。带有“0”的“最大”电话只是说,如果我们处于负数,我们就无法分配任何股票。

   -- allocated sells 
   sell.previous_sells - buy.previous_sells

   -- shares yet to sell for this buy, if < 0 then 0
   GREATEST(buy.shares - (sell.previous_sells - buy.previous_sells), 0)

   -- number of sell shares that need to be skipped
   buy.previous_net_shares

感谢大卫的协助 https://stackoverflow.com/questions/8813743/can-multiple-rows-within-a-window-be-referenced-by-an-analytic-function

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Oracle SQL 进行带有一些逻辑网络的汇总查询 的相关文章

  • 私人聊天系统MYSQL查询显示发送者/接收者的最后一条消息

    在这里我延伸一下我之前的问题 私人聊天系统MYSQL查询ORDERBY和GROUPBY https stackoverflow com questions 10929366 private chat system mysql query o
  • 使用 Hibernate 将 Oracle 日期映射到 Java 对象

    我收到消息 文字与格式字符串不匹配 例如 以下是 Java 类中的一些方法 public String getDateTime public void setDateTime String date time 以下是该类的 Hibernat
  • 如何计算选择查询的最佳获取大小

    在 JDBC 中 默认获取大小为 10 但我想当我有一百万行时 这不是最佳获取大小 据我所知 获取大小太低会降低性能 但如果获取大小太高也会降低性能 我怎样才能找到最佳尺寸 这对数据库端有影响吗 它会占用大量内存吗 如果您的行很大 请记住
  • 我应该使用平面表还是标准化数据库?

    我目前正在开发一个使用 MySQL 数据库作为后端的 Web 应用程序 在继续下一步之前 我需要知道什么更适合我的情况 简而言之 在这个应用程序中 用户将能够使用任何数字字段 他们决定 构建自己的表单 现在我将其全部存储在通过外键链接的几个
  • 如何进行数据透视并计算列平均值

    我承认这是迄今为止我必须面对的最复杂的 SQL 语句之一 我在这件事上碰壁了 我希望有人能帮我一把 我在数据库中有这张表 Item ActiveTime sec DateTime 1 10 2013 06 03 17 34 22 gt Mo
  • 如何引用下一行的数据?

    我正在 PostgreSQL 9 2 中编写一个函数 对于股票价格和日期的表 我想计算每个条目较前一天的百分比变化 对于最早一天的数据 不会有前一天 因此该条目可以简单地为 Nil 我知道WITH声明可能不应该高于IF陈述 到目前为止 这就
  • 在 MS Access SQL 查询中从正常日期转换为 unix 纪元日期

    我正在尝试编写一个通过 ODBC 连接到 MySQL 数据库的 MS Access 2007 连接的查询 一切工作正常 查询执行我想要的操作 我挂断的部分是我一直在询问用户 unix 纪元时间 而不是常规日期 我查找了 MS Access
  • 如何使用 Hibernate (EntityManager) 或 JPA 调用 Oracle 函数或过程

    我有一个返回 sys refcursor 的 Oracle 函数 当我使用 Hibernate 调用该函数时 出现以下异常 Hibernate call my function org hibernate exception Generic
  • Oracle即时客户端和Oracle客户端之间的区别

    Oracle即时客户端和Oracle客户端有什么区别 你能给我解释一下吗 谢谢 Oracle 客户端附带一个安装程序和许多可执行文件 例如 sqlplus tnsping 很完整而且很大 Oracle Instant 客户端是一个基本的轻量
  • 没有为 1 个或多个必需参数给出值。更新SQL

    我正在编写一个程序 当用户在列表视图上选择记录时 该程序会更新密码或积分 我收到错误 没有为 1 个或多个必需参数给出值 我不知道如何纠正 我是否遗漏了一些明显的东西 Dim sql As String UPDATE Users SET P
  • 根据由另一列分组的不同列的最大值获取值[重复]

    这个问题在这里已经有答案了 我想根据由另一列分组的不同列的最大值来获取列的值 我有这张表 KEY NUM VAL A 1 AB B 1 CD B 2 EF C 2 GH C 3 HI D 1 JK D 3 LM 并想要这样的结果 KEY V
  • 使用联接更新表?

    我正在尝试使用表 B 中的数据更新表 A 我以为我可以做这样的事情 update A set A DISCOUNT 3 from INVOICE ITEMS A join ITEM PRICE QUNTITY B on A ITEM PRI
  • 插入具有多个值的外键

    我想知道 是否有可能创建一个表 其中我有一个接受外键但同一行可能有多个值的表 例如 Employee id name skillid Skill Skillid skillname 这里 Employee 的一个例子可以是 Employee
  • 选择多列 按一列分组 按计数排序

    我在Oracle中有以下数据集 c1 c2 c3 1A2 cat black 1G2 dog red B11 frog green 1G2 girl red 试图得到以下结果 基本上我首先尝试获取具有重复 c1 的行 c1 c2 c3 1G
  • 带有可变 WHERE 子句的批量 UPDATE 表

    我有一堆值对 foo1 bar1 foo2 bar2 我想做一堆更新 将 foo 列设置为 foo1 其中 bar 列为 bar1 我正在使用 psycopg2 在 Python 中执行此操作 我可以executemany与查询UPDATE
  • 如何使用 Oracle 移动文本文件

    我有两个问题 1 如何从文件夹中移动文本文件 C Data inbox test txt 目标文件夹 C Data outbox test txt 2 如何获取文件夹中的目录文件列表 C Data inbox 谢谢 Oracle 提供了一个
  • Snowflake 中的动态 SQL

    当我在雪花中运行动态 SQL 时 遇到以下错误 未完成对 SQL MAIN 的分配 因为值超出了变量的大小限制 它的大小是263 限制为 256 内部存储大小以字节为单位 这是代码 SET v G 1 SET v G1 v G VARCHA
  • Java、Oracle 中索引处缺少 IN 或 OUT 参数:: 1 错误

    您好 我使用 Netbeans 8 0 2 和 Oracle 11g Express Edition 在 JSF 2 2 中编写了一个图书馆管理系统 我有几个名为 书籍 借阅者 等的页面 以及数据库中一些名为相同名称的表 我的问题是这样的
  • IIF(...) 不是公认的内置函数

    我正在尝试在 Microsoft SQL Server 2008 R2 中使用它 SET SomeVar SomeOtherVar IIF SomeBool value when true value when false 但我收到一个错误
  • 在Oracle中使用IW和MM

    我使用 IW 表示每周结果 使用 MM 表示每月结果 但我总是收到错误 ORA 00979 not a GROUP BY expression 00979 00000 not a GROUP BY expression 我的疑问是这些 We

随机推荐

  • 单击按钮的用户脚本

    我想使用greasemonkey 单击 立即购买 按钮 UserScript name script namespace sc include version 1 require http ajax googleapis com ajax
  • 理解 kubernetes 容器上的“stdin: true tty: true”?

    我已经在网上到处做好了准备 但答案并没有得到彻底的解释 我希望这个问题如果得到解答 可以提供对此事的更新和彻底的解释 为什么有人会使用以下参数定义容器 stdin true tty true Also if docker run it 将执
  • jQuery 将光标向后移动“X”个空格

    我需要它 以便当按下按钮时 光标将 1 找到句子的结尾 2 将光标从句末向后移动 x 多个空格 x为变量 这是一个小提琴 gt jsFiddle http jsfiddle net jcP9q HTML span From the end
  • 时间复杂度单循环与多个顺序循环

    今天 我和我的同事就一个特定的代码片段发生了一场小争论 代码看起来像这样 至少 他想象中是这样的 for int i 0 i lt n i Some operations here for int i 0 i lt m i m is alw
  • 使用 javascript jQuery 突出显示 html 中的文本

    我想以编程方式突出显示 p 标记中的所有关键字 不区分大小写 如果关键字是 var keywords hello thanks goodbye this should be an array p hello world p 你好应该以蓝色突
  • 如何在 C# / winforms 中将图像裁剪为圆形?

    编辑 重复 问题中给出的代码没有为我解决问题 我遇到的主要问题是我不能简单地使用 CSS 和 radius 这很容易 这是在 winforms 页面 项目中加载的图像 我必须尝试将正方形 矩形图像变成圆形 我尝试了以下两种方法 结果将发布在
  • 在 C# 中强制保留两位小数[重复]

    这个问题在这里已经有答案了 我有这个问题 找不到解决方案 这非常简单 我不知道为什么我找不到解决方案 问题 如果一个值返回例如 16 60 在c 中我将读取 16 6 但我也需要0 因为paypal API只接受没有小数的值 或者它必须有小
  • pyproject.toml 没有安装我的包依赖项

    这是我第一次与pyproject toml我的印象是 当你列出包裹时abc作为项目的依赖项之一 该包的依赖项也会被安装 即使它们没有明确列出 这是我目前的pyproject toml build system requires setupt
  • 带有 varchar(255) PRIMARY KEY 的表会造成什么损害吗?

    我知道这不是一个好主意 但我想仔细检查一下这不会造成服务器崩溃等疯狂的事情 CREATE TABLE dbo Items Id nvarchar 255 NOT NULL PRIMARY KEY Value nvarchar max NOT
  • 可可豆荚和 Watchkit 扩展

    我尝试为我的应用程序构建一个 WatchKit 扩展 我将 pods 文件更新为如下所示 platform ios 8 0 use frameworks source https github com CocoaPods Specs git
  • 如何避免在连接 (.) 中使用未初始化的值?在 Perl v5.8.4 中 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions perl e use warning
  • 如何在 Matlab 中运行 java .jar

    我需要在 Matlab 中运行 Java jar 文件 我们将文件命名为 MyJar jar 如果有帮助的话 我正在运行 Java 1 8 0 121 b13 我尝试了不同的解决方案 并收到了这些相应的错误 java jar MyJar j
  • 动态启用/禁用 mvc 服务器端验证

    我有一个 mvc 表单multiple提交按钮 保存草稿 和 发布 目的是在单击 保存草稿 按钮并提交表单时跳过客户端 javascript 无阻碍 验证和服务器端验证 但如果单击 发布 按钮 我确实需要触发这两个验证 我的研究让我找到了一
  • 如何使用CSS的bootstrap删除屏幕底部生成的空白?

    我一直在尝试创建一个简单的 html 页面 我需要将 html 覆盖到整个页面高度 但底部留有小空间 在移动设备上打开时看起来更奇怪 请帮忙检查链接 https lp codes github io Random Quote Generat
  • 如何在 jquery 中的第一个子 div 之后追加元素?

    假设我有以下 div div div 1 div div 2 div div 3 div div 4 div div 我怎样才能在 jquery 或 javascript 中做到这一点 以便我可以在 mydiv 的第一个子元素之后附加一个元
  • 困惑于在 Azure 部署的 Web.config 中存储密码的正确过程是什么

    在将 MVC 5 应用程序放到 Azure 上时 我有过一次非常令人沮丧的经历 我一直在阅读以下页面 http www asp net identity overview features api best practices for de
  • 两列上的唯一键可交换

    请建议我如何比较地在两列上应用唯一键 即假设我们有两列 FK Col1 和 FK Col2 如果我们在两列中插入 2 和 6 那么我们应该无法在两列中再次插入 2 和 6 或 6 和 2 请建议我如何实现这一目标 提前致谢 创建一个计算列及
  • 如何使用箭头键在屏幕上移动图形?

    我正在尝试创建一个简单游戏的开始 我想做的第一件事是将图形导入到我的代码中并将其移动到屏幕上 我能够在屏幕上画一个球并移动它 但是当我从文件导入图形时 我无法移动它 我错过了什么或做错了什么 import javax swing impor
  • Android Camera2视频播放视频和音频不同步

    我在使用 android 相机 2 api 时遇到了问题 我可以录制视频 但在播放过程中 仅播放音频 视频播放完毕后 时间会提前 10 分钟到 2 小时 然后播放视频 我从来没有听说过这样的问题 我几乎关注了this https githu
  • 使用 Oracle SQL 进行带有一些逻辑网络的汇总查询

    我有一个如下表 AuctionResults Auction Action Shares ProfitperShare Round1 BUY 6 200 Round2 BUY 5 100 Round2 SELL 2 50 Round3 SE