按ID更新所有记录的日期,按年增量

时间:2014-06-05 23:32:25

标签: sql ms-access

如果我有这样的数据:

create table t (PID int identity,
                        AwardDate date,
                        PytUnits int,
                        PytDate date,
                        AwardID int);

insert into t values 
('1/1/2014', '5', '1/1/2014', 1),
('1/1/2014', '5', '1/1/2015', 1),
('1/1/2014', '5', '1/1/2016', 1),
('1/1/2014', '5', '1/1/2012', 2),
('1/1/2014', '5', '1/1/2013', 2),
('1/1/2014', '5', '1/1/2014', 2),
('1/1/2014', '5', '1/1/2015', 2)
;

(see this in SQL Fiddle)

如何将PytDate(如果是> Today's date更新到第一个记录的下个月的第一天,以及将每年增加1之后的每个记录更新AwardID {1}}?

重要说明:数据库实际上是MS Access,但是我的小提琴是在SQL服务器上用作示例,希望生成一个我可以运行并转换为Access SQL的答案。

1 个答案:

答案 0 :(得分:1)

在TSQL中,最简单的方法是使用公用表表达式。但是,MSAccess没有此功能。所以下面的TSQL,虽然它在SQL Server 2008及更高版本中工作,但在MSaccess中不起作用。如果您需要MSAccess查询来执行此操作,请告诉我们。创建一个执行它的Sub Routine可能更简单。

;with Awards(NewDate, RowID, AwardRowId, PID,
                            AwardDate ,
                            PytUnits,
                            PytDate ,
                            AwardID )    --CTE Syntax set up columns
    as
    (select NewDate = case when PytDate> getdate() then convert(varchar(7), convert(date, dateadd(month, 1, getdate())))+'-01' else PytDate end   --Generate a new date based on the rules provided in question i.e. for future dates use next month, this is temporary value as we override it in the output if the other rule is met this row is only used for the first row
    , RowID = ROW_NUMBER() over (order by PID)  --RowID is simple row number for each row of output based on PID which is Primary key
    , AwardRowId = DENSE_Rank() over (order by AwardId) --Generate a RowID based on AwardId for each change in AwardID as it comes to us
    , *  --all other columns
    FROM t where PytDate> getdate()  --we are only interested in future dated data
     )
    Select CalcDate = case RowID   
        when 1 then NewDate                                 --first row is special use the next month value
        else dateadd(year, AwardRowId,     AwardDate) end   --other rows get a new date based on the row position by Award and we add a year for each change in AwardId to the base award date
    , * 
    from Awards
    order by PID

如果您希望在MSaccess中模拟这个,您可以创建4个将此逻辑链接在一起的查询

Query1 - 获取FirstOfNextMonth作为简单计算并查找未来记录 Query2 - 获取奖项列表 Query3 - 生成DenseRank 查询4 - 结果

查询1     SELECT t。*,IIf([pytdate]> Now(),DateSerial(Year(DateAdd(“m”,1,[PYTDATE])),Month(DateAdd(“m”,1,[PYTDATE])), 1),[PYTDATE])AS FirstOfMonth,[pytdate]> Now()AS IsFuture     从T     WHERE(((t.PytDate)> Now()));

QUERY2     SELECT Query1.AwardID     FROM Query1     GROUP BY Query1.AwardID     ORDER BY Query1.AwardID;

QUERY3     SELECT A.AwardId,Count(*)AS dense_rank     FROM query2 AS A LEFT JOIN query2 AS B ON B.AwardId< = A.AwardId     GROUP BY A.AwardId;

Query4     SELECT Query1。*,IIf([dense_rank] = 1,[FirstOfMonth],DateAdd(“yyyy”,[dense_rank],[pytdate]))AS NewDate,Query3.dense_rank     FROM Query1 INNER JOIN Query3 ON Query1.AwardID = Query3.AwardId     ORDER BY Query3.dense_rank,Query1.PytDate;