以下示例数据具有每个条目的累积大小。我正在尝试编写一个查询来更新大小,大小与前一个时间戳的差异(例如 - 第2行应更新为(4478.74 - 4476)= 2.74)对于相同的项目名称。请帮我解决这个问题。
Row Item Size Time
-----------------------------------------------
1 ItemA 4476 7/01/2012 11:15
2 ItemA 4478.74 7/01/2012 11:20
3 ItemA 4478.82 7/01/2012 11:21
4 ItemA 4487.51 7/01/2012 11:29
5 ItemB 1.53 7/01/2012 11:29
6 ItemB 1.67 7/01/2012 11:20
7 ItemB 1.84 7/01/2012 11:21
8 ItemB 2.18 7/01/2012 11:15
答案 0 :(得分:2)
您可以按项目对数据进行分区,然后将其外部连接到上一行编号:
create table ItemTotal (id uniqueidentifier, item varchar(10), size numeric(10,2), entry datetime)
insert into ItemTotal values(NEWID(), 'ItemA', 4476, '7/01/2012 11:15');
insert into ItemTotal values(NEWID(), 'ItemA', 4478.74, '7/01/2012 11:20');
insert into ItemTotal values(NEWID(), 'ItemA', 4478.82, '7/01/2012 11:21');
insert into ItemTotal values(NEWID(), 'ItemA', 4487.51, '7/01/2012 11:29');
insert into ItemTotal values(NEWID(), 'ItemB', 1.53, '7/01/2012 11:29');
insert into ItemTotal values(NEWID(), 'ItemB', 1.67, '7/01/2012 11:20');
insert into ItemTotal values(NEWID(), 'ItemB', 1.84, '7/01/2012 11:21');
insert into ItemTotal values(NEWID(), 'ItemB', 2.18, '7/01/2012 11:15');
with items(id, item, size, entry, rn) as (
select id, item, size, entry, ROW_NUMBER () OVER (Partition By item order by entry) as rn From ItemTotal t)
select i.item, i.size, i.entry, i.size - coalesce(o.size, 0) as difference
from items i
left outer join items o on o.item = i.item and o.rn = i.rn-1
order by i.item, i.entry desc
结果输出:
item size entry difference
ItemA 4487.51 2012-07-01 11:29:00.000 8.69
ItemA 4478.82 2012-07-01 11:21:00.000 0.08
ItemA 4478.74 2012-07-01 11:20:00.000 2.74
ItemA 4476.00 2012-07-01 11:15:00.000 4476.00
ItemB 1.53 2012-07-01 11:29:00.000 -0.31
ItemB 1.84 2012-07-01 11:21:00.000 0.17
ItemB 1.67 2012-07-01 11:20:00.000 -0.51
ItemB 2.18 2012-07-01 11:15:00.000 2.18
答案 1 :(得分:0)
您的数据无序。第8行早于第5-7行。我猜你想最早开始,然后从那里开始。
因此,假设表定义为:
create table ItemTotal (itemTotalId int, item varchar(10), size numeric(10,2),
entry datetime, sizeDifferential numeric(10,2));
以下两次连接自身以查找相同项类型的最新上一个时间戳。因此,这忽略了rownumber,这通常是一个很好的RDBMS实践。 (我不确定它是否真的是表格的一部分,或者只是你问题中的标识符。)
update ItemTotal
set newSize = coalesce((size -
(select size
from ItemTotal IT2
where ItemTotal.item = IT2.item
and IT2.entry < ItemTotal.entry
and not exists (select * from ItemTotal IT3
where IT2.item = IT3.item
and IT3.entry > IT2.entry
and IT3.entry < ItemTotal.entry)
)
), size);
这种进行连接的特殊方法是找到一个前一次的行,其中不存在比选择的IT2行更新的另一行,但是小于源ItemTable行。
您也可以使用max(条目)将此最内层查询写入 - 目前尚不清楚哪个更快。
这个输出是:
ITEM SIZE ENTRY NEWSIZE
1 ItemA 4476 July, 01 2012 11:15:00-0700 4476
2 ItemA 4478.74 July, 01 2012 11:20:00-0700 2.74
3 ItemA 4478.82 July, 01 2012 11:21:00-0700 0.08
4 ItemA 4487.51 July, 01 2012 11:29:00-0700 8.69
5 ItemB 1.53 July, 01 2012 11:29:00-0700 -0.31
6 ItemB 1.67 July, 01 2012 11:20:00-0700 -0.51
7 ItemB 1.84 July, 01 2012 11:21:00-0700 0.17
8 ItemB 2.18 July, 01 2012 11:15:00-0700 2.18
如果你直接更新这个尺寸,你显然只能运行一次。对于一次性更新,我更愿意更新到临时表/列,验证结果,然后反映回原始列。
注意:像这样的更新中的相关自联接将在几个dbs(mysql)中失败,但在大多数其他(例如MSSQL)中都有效。