【问题标题】:SQL query to calculate stock order data?SQL查询计算库存订单数据?
【发布时间】:2020-01-09 09:43:48
【问题描述】:

我有一张表格,其中包含如下所示的股票订单:

第一列是相应股票的ID,第二列是订单价格,第三列是买入(买)还是卖出(卖出)最后一列是剩余的交易量命令。

我想要做的是获取这些值:

  • 最高和最低出价以及最高和最低要价。
  • 最高出价和最低要价的总和

我意识到这是一个相当复杂的查询,它可能会涉及一个(或者可能是几个子查询),但我目前的情况是这样的:

SELECT
  SYMBOL_CODE as symbol_code,
  MAX(ORDER_PRICE) as highest_bid,
  MIN(ORDER_PRICE) as lowest_bid,
  SUM(VOLUME_TRADED)
FROM ORDERS
WHERE
  ORDER_TYPE = 'buy'
GROUP BY
  SYMBOL_CODE
order by
  SYMBOL_CODE;

在我看来,这有两个问题,首先,它汇总了所有价格的交易量,而不仅仅是最高出价订单的价格,无法弄清楚如何做到这一点,其次,这只对出价,我不得不为询问写另一个查询。我尝试按 order_type 进行分组,但没有得到预期的结果(股票有 1 行或 2 行结果,具体取决于它们是否有买/卖单或两者兼有)

【问题讨论】:

  • 编辑问题添加预期结果。
  • 我必须添加大量示例数据,以便您了解它们如何影响输出。如果它们不够清楚,我可以更多地解释所需的值。我还可以添加.sql 文件
  • 您的预期输出样本将有所帮助

标签: sql sql-server


【解决方案1】:

您可以使用row_number()过滤表格中的最高价和最低价,然后进行条件聚合:

select
    symbol_code,
    max(case when order_type = 'buy' and rn_high = 1 then order_price end) highest_bid,
    sum(case when order_type = 'buy' and rn_high = 1 then volume_traded end) volume_at_highest_bid,
    min(case when order_type = 'sell' and rn_low = 1 then order_price end) lowest_ask,
    sum(case when order_type = 'sell' and rn_low = 1 then volume_traded end) volume_at_lowest_ask
from (
    select
        o.*,
        row_number() over(partition by symbol_code, order_type order by order_price) rn_low,
        row_number() over(partition by symbol_code, order_type order by order_price desc) rn_high
    from orders o
) t
where 
    order_type = 'buy' and rn_high = 1
    or (order_type = 'sell' and rn_low = 1)
group by symbol_code

【讨论】:

  • 什么是rn_high和rn_low?
  • @ninesalt:这些是row_number()s,我们用它来识别最高出价和最低要价。
  • @ninesalt 他们基本上是排名。
  • 我收到一条错误消息,提示 Invalid column name 'volume_traded'.,即使这就是该列的名称
  • 好的,现在它执行了,但是有很多空值。这也不会选择最低出价和最高要价
【解决方案2】:

我创建了一个如下视图以保留所有指定的详细信息,然后根据视图从视图中进行选择

订单量

和

类型

列。

alter view MinMax as
select [SYMBOL_CODE] as Symbol,
        MAX(ORDER_PRICE) as 'Price',
        'Max' as 'Type',
        case max(order_type) when 'buy' then 'BID'  
        else 'ASK'
        end as 'Order Type' ,
        'Order' as 'Order_Volume'
        FROM ORDERS
where ORDER_PRICE in(select MAX(ORDER_PRICE) FROM ORDERS)
group by [SYMBOL_CODE]
union 
select SYMBOL_CODE ,
        sum(VOLUME_TRADED),
        'Max',
        case max(order_type) when 'buy' then 'BID'
        else 'ASK'
        end ,
        'Order'
        FROM ORDERS
where VOLUME_TRADED in(select MAX(VOLUME_TRADED) FROM ORDERS)
group by [SYMBOL_CODE]
union
select SYMBOL_CODE as Symbol,
       MAX(ORDER_PRICE),
       'Max',
       'BID',
        'Volume' 
        FROM ORDERS
where VOLUME_TRADED in(select MAX(VOLUME_TRADED) FROM ORDERS) and order_type='buy'
group by [SYMBOL_CODE]
union
select SYMBOL_CODE,
       MAX(ORDER_PRICE),
        'Min',
        'ASK',
        'Volume'
        FROM ORDERS
where VOLUME_TRADED in(select min(VOLUME_TRADED) FROM ORDERS) and order_type='sell'
group by [SYMBOL_CODE]

如果您还想根据预算类型获得订单,我还添加了一个名为“OrderType”的新列。 从视图中选择得到指定的结果。

Select * from minmax

如果您只想要 SYMBOL_ID 和价格,那么:

select symbol,price from minmax

【讨论】:

  • MAX(SYMBOL_CODE)?
  • @ninesalt 我以为你只想要最小和最大行对不起。我使用 GroupBy 做了一些更改。我希望它现在对你有帮助。
【解决方案3】:

除了 Partition-- 函数之外,您是否尝试过使用 Min()/Max() 函数? 这样您就可以将查询结果“拆分”为每个“符号代码”分区并获得相应的最小值/最大值

因为看起来,您真正想做的是查看某个“符号代码”的所有数据,然后“迭代”它们

【讨论】:

    【解决方案4】:

    我认为窗口函数和适当的聚合可以满足您的需求:

    select symbol_code, max_buy, min_ask,
           sum(case when order_type = 'buy' and order_price = max_buy then volume_traded) as max_buy_volume,
           sum(case when order_type = 'sell' and order_price = min_ask then volume_traded) as min_ask_volume
    from (select o.*,
                 max(case when order_type = 'buy' then order_price end) over (partition by symbol_code) as max_buy,
                 min(case when order_type = 'sell' then order_price end) over (partition by symbol_code) as min_ask
           from orders o
          ) o
    group by symbol_code, max_buy, min_ask;
    

    【讨论】:

    • @ninesalt 。 . . os 周围没有明显的语法错误。
    猜你喜欢
    • 2020-05-08
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2021-02-15
    • 2017-08-12
    • 2020-05-14
    • 2016-08-24
    • 2019-07-20
    相关资源
    最近更新 更多