我想根据上个月

时间:2017-08-28 17:27:05

标签: sql-server

ID      TagValue            DATESTR
1           23         2017-01-25 12:01:48.007
2           34         2017-01-25 12:01:48.007
3           44         2017-01-25 12:01:48.007
1           25         2017-02-25 12:01:48.007
2           36         2017-02-25 12:01:48.007
3           46         2017-02-25 12:01:48.007
1           27         2017-03-25 12:01:48.007
2           36         2017-03-25 12:01:48.007
3           48         2017-03-25 12:01:48.007
1           29         2017-04-25 12:01:48.007
2           38         2017-04-25 12:01:48.007
3           50         2017-04-25 12:01:48.007
1           31         2017-05-25 12:01:48.007
2           40         2017-05-25 12:01:48.007
3           52         2017-05-25 12:01:48.007
1           33         2017-06-25 12:01:48.007
2           42         2017-06-25 12:01:48.007
3           54         2017-06-25 12:01:48.007
1           44         2017-07-25 12:01:48.007
2           46         2017-07-25 12:01:48.007
3           56         2017-07-25 12:01:48.007
1           48         2017-08-25 12:01:48.007
2           58         2017-08-25 12:01:48.007

这是我的主表,其中值与日期时间一致

ID  LastMonthvalue  CurrentMonthValue   DATESTR
 1          23             25          2017-03-28 12:01:48.007
 2          34             36          2017-03-28 12:01:48.007
 3          44             46          2017-03-28 12:01:48.007

这是我的第二个表,我想根据我的主表更新LastMonth Value和CurrentMonth Value,因为你可以看到我的主表中添加了新值(ID = 1)在我的第二个表中我已经有3个ID了值假设我想今天更新我的第二张表2017-08-30,而不是更新2017-07-25的lastMonthValue值和2017-08-25从Master表更新CurrentMonth值

2 个答案:

答案 0 :(得分:0)

一个月内可能有多行吗?

;with tb(ID,TagValue,TagValue1,DATE) AS (
     select 1,234,345,'2017-07-21 13:15:09.387' union all
     select 2,444,555,'2017-07-21 13:15:09.387' union all
     select 1,356,545,'2017-08-21 13:15:09.387'
)
select ID
       ,sum(case when datediff(month,[DATE],getdate())=1 then  TagValue else 0 end) as LastMonth
       ,sum(case when datediff(month,[DATE],getdate())=0 then  TagValue else 0 end) as CurrentMonth
from tb 
where datediff(month,[DATE],getdate())<=1
group by ID
    ID  LastMonth   CurrentMonth
1   1   234 356
2   2   444 0

答案 1 :(得分:0)

我创建了两个答案,一个用于SQL Server 2008,另一个用于2012年以上。

这种逻辑如何运作

  • cte_PreviousMonth - 发现当月的第一天和 上个月
  • cte_Dates - 获取工作日期cte_Main - 过滤 回溯过去两个月的日期
  • cte_MainCurrent - 计算最后和当前值
  • 更新第二张表

也许,您需要做一些调整才能实现目标

 DECLARE @Master AS TABLE 
  ( 
     id        INT, 
     TagValue  INT,  
     DATESTR    DATETIME 
  ) 
DECLARE @Second  as table (
ID  int , LastMonthValue  int, CurrentMonthValue   int, DATESTR date)
 INSERT @Second
 VALUES 
  (1          ,23             ,25          ,'2017-03-28 12:01:48.007')
 ,(2          ,34             ,36          ,'2017-03-28 12:01:48.007')
 ,(3          ,44             ,46          ,'2017-03-28 12:01:48.007')

INSERT @Master  
VALUES 
 (1           ,23         ,'2017-01-25 12:01:48.007')
,(2           ,34         ,'2017-01-25 12:01:48.007')
,(3           ,44         ,'2017-01-25 12:01:48.007')
,(1           ,25         ,'2017-02-25 12:01:48.007')
,(2           ,36         ,'2017-02-25 12:01:48.007')
,(3           ,46         ,'2017-02-25 12:01:48.007')
,(1           ,27         ,'2017-03-25 12:01:48.007')
,(2           ,36         ,'2017-03-25 12:01:48.007')
,(3           ,48         ,'2017-03-25 12:01:48.007')
,(1           ,29         ,'2017-04-25 12:01:48.007')
,(2           ,38         ,'2017-04-25 12:01:48.007')
,(3           ,50         ,'2017-04-25 12:01:48.007')
,(1           ,31         ,'2017-05-25 12:01:48.007')
,(2           ,40         ,'2017-05-25 12:01:48.007')
,(3           ,52         ,'2017-05-25 12:01:48.007')
,(1           ,33         ,'2017-06-25 12:01:48.007')
,(2           ,42         ,'2017-06-25 12:01:48.007')
,(3           ,54         ,'2017-06-25 12:01:48.007')
,(1           ,44         ,'2017-07-25 12:01:48.007')
,(2           ,46         ,'2017-07-25 12:01:48.007')
,(3           ,56         ,'2017-07-25 12:01:48.007')
,(1           ,48         ,'2017-08-25 12:01:48.007')
,(2           ,58         ,'2017-08-25 12:01:48.007')

更新前

SELECT * FROM @Second

ID          LastMonthValue CurrentMonthValue DATESTR
----------- -------------- ----------------- ----------
1           23             25                2017-03-28
2           34             36                2017-03-28
3           44             46                2017-03-28

Code ror SQL Server 2008

;WITH  
cte_PreviousMonth
as
(
    Select Distinct 
     Id 
    ,DateAdd(M,-1,Cast(CAST(Datepart(YYYY, Max(DATESTR) Over (Partition by Id)) * 100 +  Datepart(MM, Max(DATESTR) Over (Partition by Id)) as char(6)) +'01' as date)) DATESTR_Previous
    ,Cast(CAST(Datepart(YYYY, Max(DATESTR) Over (Partition by Id)) * 100 +  Datepart(MM, Max(DATESTR) Over (Partition by Id)) as char(6)) +'01' as date) DATESTR_CurrentStartMonth
    ,DATESTR
    from @Master 
)
,cte_Dates as
(
    Select Distinct A.Id , 
     Max(A.DATESTR) Over (Partition by A.Id) DATESTR_Previous
    ,Max(B.DATESTR) Over (Partition by B.Id) DATESTR_Current
    from @Master A 
    INNER JOIN cte_previousMonth b
    On 
     a.id = b.id and a.DATESTR >= b.DATESTR_Previous and a.DATESTR < b.DATESTR_CurrentStartMonth
)
,cte_Main AS 
(
SELECT Row_number() 
                  OVER ( 
                    partition BY id 
                    ORDER BY DATESTR) rn
                ,* 
         FROM   @Master A
         where exists (Select 1 from cte_Dates b where a.id =b.id and (a.DATESTR = b.DATESTR_Previous or a.DATESTR = b.DATESTR_Current))
)
,cte_MainCurrent as ( 
SELECT ROW_NUMBER() over (partition by a.id order by a.DATESTR desc) rn
       ,a.id
       ,a.DATESTR
       ,b.tagvalue LastMonthvalue
       ,a.tagvalue CurrentMonthValue 
FROM   cte_Main a 
       LEFT JOIN cte_Main b 
              ON a.id = b.id 
                 AND a.rn = b.rn + 1 
) 
UPDATE 
    S
SET
    LastMonthValue = M.LastMonthvalue
    ,CurrentMonthValue = M.CurrentMonthValue
    ,DATESTR = M.DATESTR
FROM @Second S
INNER JOIN cte_MainCurrent M
On
    S.ID = M.id
WHERE
    M.rn = 1

上面的SQL Server 2012代码

;WITH  
cte_PreviousMonth
as
(
    Select Distinct 
     Id 
    ,DateAdd(M,-1,Cast(CAST(Datepart(YYYY, Max(DATESTR) Over (Partition by Id)) * 100 +  Datepart(MM, Max(DATESTR) Over (Partition by Id)) as char(6)) +'01' as date)) DATESTR_Previous
    ,Cast(CAST(Datepart(YYYY, Max(DATESTR) Over (Partition by Id)) * 100 +  Datepart(MM, Max(DATESTR) Over (Partition by Id)) as char(6)) +'01' as date) DATESTR_CurrentStartMonth
    ,DATESTR
    from @Master 
)
,cte_Dates as
(
    Select Distinct A.Id , 
    Max(A.DATESTR) Over (Partition by A.Id) DATESTR_Previous
    ,Max(B.DATESTR) Over (Partition by B.Id) DATESTR_Current
    from @Master A 
    INNER JOIN cte_previousMonth b
    On 
     a.id = b.id and a.DATESTR >= b.DATESTR_Previous and a.DATESTR < b.DATESTR_CurrentStartMonth
)
,cte_MainCurrent as ( 
SELECT ROW_NUMBER() over (partition by a.id order by a.DATESTR desc) rn
        ,id
       ,DATESTR
       ,Lag(tagvalue, 1, NULL) 
         OVER ( 
           partition BY id 
           ORDER BY DATESTR) LastMonthvalue, 
       tagvalue             CurrentMonthValue 
FROM   @Master a
    where exists (Select 1 from cte_Dates b where a.id =b.id and (a.DATESTR = b.DATESTR_Previous or a.DATESTR = b.DATESTR_Current))
) 
UPDATE 
    S
SET
    LastMonthValue = M.LastMonthvalue
    ,CurrentMonthValue = M.CurrentMonthValue
    ,DATESTR = M.DATESTR
FROM @Second S
INNER JOIN cte_MainCurrent M
On
    S.ID = M.id
WHERE
    M.rn = 1

更新后

SELECT * FROM @Second
ID          LastMonthValue CurrentMonthValue DATESTR
----------- -------------- ----------------- ----------
1           44             48                2017-08-25
2           46             58                2017-08-25
3           54             56                2017-07-25