SQL:将大小聚合到容器中
我有一个(Sybase)表,其中包含以下信息:SQL:将大小聚合到容器中,sql,sap-ase,Sql,Sap Ase,我有一个(Sybase)表,其中包含以下信息: order_id int timestamp datetime action char(1) --i=inserted, c=corrected, r=removed shares int 它跟踪系统中与订单(由其订单id标识)关联的共享。 举例来说,订单的有效期如下所示: timestamp action shares 10:00:00 i 1000
order_id int
timestamp datetime
action char(1) --i=inserted, c=corrected, r=removed
shares int
它跟踪系统中与订单(由其订单id标识)关联的共享。
举例来说,订单的有效期如下所示:
timestamp action shares
10:00:00 i 1000 -- initial Insert
10:06:30 c 900 -- one Change
10:07:12 c 800
10:50:20 r 800 -- Removal
11:10:10 i 600 -- 2nd Insert
11:12:10 r 600
在上面的示例中,订单从10:00:00和10:50:20起激活,从11:10:10和11:12:10再次激活
我在系统中有1000个这样的订单,我需要用柱状图绘制一个时间序列中有多少个股票处于活动状态,分为5分钟的仓位/桶。
如果给定订单的股票数量在此处的samenter代码内变化不止一次,我需要对股票进行平均;如上述10:05-10:10箱中的示例所示,其中1000、900和800可以平均为900
下面是一个更复杂的示例:
1, "20140828 10:00:00", "i", 1000
1, "20140828 10:06:00", "c", 900
1, "20140828 10:07:12", "c", 500
1, "20140828 10:10:10", "c", 400
1, "20140828 10:20:20", "r", 400
1, "20140828 10:30:10", "i", 300
1, "20140828 10:32:10", "r", 300
2, "20140828 09:51:00", "i", 500
2, "20140828 10:08:30", "r", 500
3, "20140828 10:10:00", "i", 1000
3, "20140828 10:11:20", "r", 1000
其预期产出:
10:00:00 1500
10:05:00 1300
10:10:00 1450
10:15:00 400
10:20:00 400
10:25:00 0
10:30:00 300
10:35:00 0
10:40:00 0
10:45:00 0
10:50:00 0
10:55:00 0
提前感谢您的帮助。这是基于(MS或Sybase,由于共享历史)的一个变体,按bucket ID分组,它可以是基本时间整数除以5的时间差(以分钟为单位)。这样做可以:
create table #t(
BucketNo int not null primary key clustered,
Activity int not null,
Active int not null
);
-- pre-aggregate activity data
-- assumes prior existence of a zero-based NUMBERS or TALLY table
insert #t(BucketNo,Activity,Active)
select
N
,isnull(Activity,0)
,0
from NUMBERS
left join (
select
datediff(mm,0,TimeStamp) / 5 as BucketNo
,case action when 'i' then +1
'r' then -1
end * shares as Activity
,0 as Active
from ActivityTable
where action <> 'c'
group by datediff(mm,0,TimeStamp) / 5
union all
select
datediff(mm,0,TimeStamp) / 5 as BucketNo
,case action when 'i' then +1
'r' then -1
end * shares
- ( select top 1 i.shares
from ActivityTable i
where i.order_id = c.order_id and i.TimeStamp > c.TimeStamp
order by i.TimeStamp desc
) as Activity
,0 as Active
from ActivityTable as c
where c.action = 'c
group by datediff(mm,0,TimeStamp) / 5
) data on data.BucketNo = N
where N < 24 * 12; -- 5 minute buckets per day
您能发布示例输入数据的预期输出结果吗?谢谢您的建议,@JaugarChang。我对我的帖子做了一些修改,添加了一个更全面的示例和预期输出。谢谢Pieter,我正在尝试您的解决方案(对Sybase进行了一些修改),但我有3个问题:1)您正在谈论的数字/理货表是什么,2)我在
select top 1 I.shares
line:关键字“top”附近出现语法错误,无法解决该语法错误。Msg 102,15级,状态181
,3)奇怪的更新会在Sybase中起作用吗?@jeromeso:Numbers table:and。是的,奇怪的更新应该在SYBASE中仍然有效,因为它早于SYBASE和SQL Server的MS风格的分离。关于语法错误,请先尝试而不是前1(按照),在使用SQL解决方案后,我意识到它比我的Perl实现慢,因此我继续使用Perl。谢谢你的建议,@PieterGeedkens!我学到了不少。
declare @Shares int = 0,
@BucketNo int = 0;
-- `quirky update` peculiar to SQL Server
update #t
set @Shares = Shares
= case when BucketNo = @BucketNo
then @Shares + Activity
else 0
end,
@BucketNo = BucketNo
from #t with (TABLOCKX) -- not strictly necessary when using a temp table.
option (MAXDOP 1); -- prevent parallelization of query
select BucketNo, Active from #t order by BucketNo
go