如何使用最近和第二个近期记录更新表

时间:2016-11-06 15:35:04

标签: sql sql-server

我尝试使用其他两个组合创建聚合表。

Feed表A:

PrimaryKey, Score, DateField
1, 50, 1/1/2016
2, 12, 1/1/2016
1, 75, 1/12/2016
1, 80, 1/15/2016
2, 35, 1/16/2016

预期结果(表B):

PrimaryKey, Score, LastScore, OtherFields...
1, 80, 75, data...
2, 35, 12, data...

在记录1中,80是最近的记录,75是最近的记录。对于表B中的所有记录,这是规则。

条件是表A中有超过2500万条记录,表B中有250万条记录。表B按表A定期更新。

我使用这样的语句:

;with cte as
(
    select 
        PrimaryKey, 
        row_number() over(partition by PrimaryKey order by DateField desc) RowNumber
    from 
        TableA
)

但我的问题是,我在解决如何使用一个匹配设置第一列以及将第二列设置为另一个匹配时遇到问题。

有更容易/更快的方法吗?我希望能在几个小时内完成这项工作,而不是几天。

感谢。

2 个答案:

答案 0 :(得分:1)

一种方法使用条件聚合:

Serial.print( ((uint32_t)(1u<<15)) >> 15, BIN);
Serial.print( ((uint16_t)(1<<15)) >> 15, BIN);
Serial.print( ((uint32_t)(uint16_t)(1<<15)) >> 15, BIN);

答案 1 :(得分:1)

如果SQL Server版本&gt; = 2012则:

declare @t table(PrimaryKey int, Score int, DateField date);

insert into @t values 
    (1, 50, '2016-01-01'),
    (2, 12, '2016-01-01'),
    (1, 75, '2016-01-12'),
    (1, 80, '2016-01-15'),
    (2, 35, '2016-01-16');

select top 1 with ties
    PrimaryKey,
    Score,
    LastScore = LAG (Score, 1, null) over (partition by PrimaryKey order by DateField),
    DateField
from
    @t
order by
    row_number() over(partition by PrimaryKey order by DateField desc);

修改:如果我理解正确,则更新将如下所示:

declare @t table(PrimaryKey int, Score int, LastScore int, DateField date);

insert into @t
    (PrimaryKey, Score, DateField)
values 
    (1, 50, '2016-01-01'),
    (2, 12, '2016-01-01'),
    (1, 75, '2016-01-12'),
    (1, 80, '2016-01-15'),
    (2, 35, '2016-01-16');


with cte as 
(
    select
        PrimaryKey,
        Score,
        LastScore = LAG (Score, 1, null) 
                        over (partition by PrimaryKey order by DateField),
        DateField
    from
        @t
)
update t set
    LastScore = cte.LastScore
from 
    @t t
    inner join cte on cte.PrimaryKey = t.PrimaryKey 
                  and cte.DateField = t.DateField               
               -- and cte.Score = t.Score 
where
    t.LastScore is null and cte.LastScore is not null;

为了加快查询速度,请确保在两个表上都有索引:

create nonclustered index IX_PrimaryKey_DateField on TableA 
(
    PrimaryKey asc,
    DateField asc
) 
include (Score);

GO

create nonclustered index  IX_PrimaryKey_DateField on TableB 
(
    PrimaryKey asc,
    DateField asc
) 
include (Score, LastScore)
where LastScore is null;