我正在尝试创建一个存储过程,以匹配买家和卖家的虚假股票市场计划。我最终想用这个来填充一个事务表来完成人们的订单。这也将在SQL Server代理作业中。这是我的表格:
Id UserId Type QtyRemaining Price CreatedOn
1 3 BUY 50 1.00 2012-09-09 05:25:48.4470000
2 6 BUY 50 1.00 2012-09-09 19:25:34.4300000
3 5 SELL 30 1.00 2012-09-09 19:22:59.5900000
4 3 SELL 50 0.90 2012-09-09 06:39:34.9100000
5 2 SELLALL 50 1.00 2012-09-09 04:10:01.8400000
进行这些匹配需要满足几个条件:
所以交易者对将是#1和#4,#2和#5。因此#3仍然有待处理。
这是我正在玩的代码,但是我无法让它与最低价格和最早的第一个匹配:
select o.*, oa.*, r.* from [Order] o
join OrderActivity oa on o.Id = oa.OrderId
join (
select o2.Id, o2.VideoId, o2.UserId, oa2.Price, oa2.QtyRemaining, o2.[Type] from [Order] o2
join OrderActivity oa2 on o2.Id = oa2.OrderId
where o2.Type = 'buy' and oa2.Status = 'open'
) as r on (o.VideoId = r.VideoId and oa.Price <= r.Price and r.QtyRemaining = oa.QtyRemaining and o.UserId != r.UserId)
where (o.Type = 'sell' or o.Type = 'sellall') and oa.Status = 'open'
答案 0 :(得分:2)
试试这个
简而言之,
1.基于createddate(在下面的查询中命名为stock)的佣金买家.2。基于价格的卖家卖家,创建日期(命名为lowNoldstock)select stocks.*,lowNoldStock.*
from (select *,row_number() over(order by createdon) as buyerrank
from stocktable(nolock) where c='buy' ) stocks
inner join
(select *,row_number() over(order by price,createdon) as sellerrank
from stocktable(nolock) where [type]='sell' or [type]='sellall' ) lowNoldstock
on (stocks.qty<=lowNoldStock.qty and lowNoldStock.type='sell')
or (lowNoldStock.type='sellall' and stocks.qty=lowNoldStock.qty and stocks.price>=lowNoldStock.price)
where lowNoldStock.sellerrank=stocks.buyerrank
test script in sql fiddle,由于某种原因,它在sql小提琴中显示部分结果 这适用于我的本地数据库
答案 1 :(得分:0)
欢迎您玩这个:
declare @Transactions as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into @Transactions ( Id, UserId, Type, QtyRemaining, Price, CreatedOn ) values
( 1, 3, 'BUY', 50, 1.00, '2012-09-09 05:25:48.447' ),
( 2, 6, 'BUY', 50, 1.00, '2012-09-09 19:25:34.430' ),
( 3, 5, 'SELL', 30, 1.00, '2012-09-09 19:22:59.590' ),
( 4, 3, 'SELL', 50, 0.90, '2012-09-09 06:39:34.910' ),
( 5, 2, 'SELLALL', 50, 1.00, '2012-09-09 04:10:01.840' )
-- Split the transactions into temporary working tables.
declare @Buyers as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
declare @Sellers as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into @Buyers
select Id, UserId, Type, QtyRemaining, Price, CreatedOn
from @Transactions
where Type = 'BUY'
insert into @Sellers
select Id, UserId, Type, QtyRemaining, Price, CreatedOn
from @Transactions
where Type like 'SELL%'
-- Process the buy orders in the order in which they were created.
declare @BuyerId as Int = ( select top 1 Id from @Buyers order by CreatedOn )
declare @SellerId as Int
declare @Balance as Int
while @BuyerId is not NULL
begin
-- Pair a seller, if possible, with the current buyer.
; with Willard as (
select Row_Number() over ( order by S.Price, S.CreatedOn ) as Priority,
S.Id as S_Id, S.QtyRemaining as S_QtyRemaining,
B.QtyRemaining as B_QtyRemaining
from @Sellers as S inner join
@Buyers as B on B.Id = @BuyerId and
case
when S.Type = 'SELL' and B.QtyRemaining <= S.QtyRemaining then 1
when S.Type = 'SELLALL' and B.QtyRemaining = S.QtyRemaining then 1
else 0
end = 1
)
select @SellerId = S_Id, @Balance = S_QtyRemaining - B_QtyRemaining
from Willard
where Priority = 1
-- Display the result.
select @BuyerId as BuyerId, @SellerId as SellerId, @Balance as RemainingShares
-- Update the working tables.
if @Balance = 0
delete from @Sellers
where Id = @SellerId
else
update @Sellers
set QtyRemaining = @Balance
where Id = @SellerId
delete from @Buyers
where Id = @BuyerId
-- Find the next buy order.
set @BuyerId = ( select top 1 Id from @Buyers order by CreatedOn )
end
-- Display any unfilled orders.
select 'Unmatched Buy', *
from @Buyers
select 'Unmatched Sell', *
from @Sellers