2017-06-29 116 views
1
activity_date Employee_id 
5/29/2017  1 
4/15/2017  1 
1/14/2017  2 
4/14/2017  2 
2/15/2017  2 
6/15/2017  3 
1/13/2017  4 

如何编写一个查询,让雇员获取最新activity_date的快照,就好像它是5/1/2017一样,然后再次循环并拍摄快照,就好像它在哪里4/1/2017等等。如何通过SQL循环查找最近的最大日期?

这是我想循环过去3个日历月的输出。

activity_date Employee_id snapshot_date 
4/15/2009  1   5/1/2017 
4/14/2009  2   5/1/2017 
1/13/2009  4   5/1/2017 
2/15/2009  2   4/1/2017 
1/13/2009  4   4/1/2017 
2/15/2009  2   3/1/2017 
1/13/2009  4   3/1/2017 

谢谢

+1

SQL Server或Oracle?请选择一个。 – scsimon

+0

我删除了不兼容的数据库标记。请仅使用您正在使用的数据库进行标记。 –

+0

您确定employee_id 1应该有4/1快照的记录吗?活动日期后将发生该快照 – scsimon

回答

0

一种方法是UNION ...

select 
    employee_id, 
    Max(activity_date) activity_date, 
    '2017-05-01' as snap_shot 
from SomeTable 
where activity_date <= '20170501' 
group by employee_id 

union 

select 
    employee_id, 
    Max(activity_date) activity_date, 
    '2017-04-01' as snap_shot 
from SomeTable 
where activity_date <= '20170401' 
group by employee_id 

union 

select 
    employee_id, 
    Max(activity_date) activity_date, 
    '2017-03-01' as snap_shot 
from SomeTable 
where activity_date <= '20170301' 
group by employee_id 

或者,如果你希望有一堆日期,use a CTE的...只是设置@启动和@结束变量

declare @table table (activity_date date, Employee_id int) 
insert into @table 
values 
('5/29/2017',1), 
('4/15/2017',1), 
('1/14/2017',2), 
('4/14/2017',2), 
('2/15/2017',2), 
('6/15/2017',3), 
('1/13/2017',4) 


DECLARE @start DATE, @end DATE; 
SELECT @start = '20170301', @end = '20170501' 

;WITH n AS 
(
    SELECT TOP (DATEDIFF(month, @start, @end) + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.all_objects 
), 

x as 
(
    SELECT DATEADD(month, n-1, @start) DT 
    FROM n 
) 



select 
    Employee_id 
    ,Max(activity_date) activity_date 
    ,DT 
from @table 
inner join x on activity_date <= DT 
group by Employee_id, DT 
order by DT desc 
+0

谢谢,员工3因为活动日期在快照日期之后没有返回任何记录。有没有办法用循环简化代码而不是做一堆工会? – Bob

+0

看到编辑@Bob,但在您的数据我不'看你是如何得到你的第4行 – scsimon

+0

谢谢,我修正了输出。联接解决方案效果很好。 – Bob

0

会是这样的工作吗?

SELECT Max(activity_date), Employee_id, '2017-05-01' AS snapshotDate 
FROM YOUR_TABLE_NAME 
WHERE activity_date <= '2017-05-01' 
GROUP BY Employee_id 

它给你造成这样的:

2017-04-15 1 2017-05-01 
2017-04-14 2 2017-05-01 
2017-01-13 4 2017-05-01 

编辑:如果你想多和循环通过它,你可以使用SQL for循环。下面是代码:

CREATE TABLE prac(
    activity_date DATE, 
    Employee_id int 
) 


INSERT INTO prac (activity_date, Employee_id) 
VALUES ('2017-05-29', 1), 
('2017-04-15', 1), 
('2017-01-14', 2), 
('2017-04-14', 2), 
('2017-02-15', 2), 
('2017-06-15', 3), 
('2017-01-13', 4) 

DECLARE @i date = '2017-05-01' 
     WHILE @i >= '2017-03-01' 
     BEGIN 
      SELECT Max(activity_date), Employee_id, @i AS snapshotDate 
      FROM prac 
      WHERE activity_date <= @i 
      GROUP BY Employee_id 

      SET @i = DATEADD(MONTH,-1,@i) 
     END 

上面的代码将通过月月环至五月和输出看起来是这样的:

2017-04-15 1 2017-05-01 
2017-04-14 2 2017-05-01 
2017-01-13 4 2017-05-01 

2017-02-15 2 2017-04-01 
2017-01-13 4 2017-04-01 

2017-02-15 2 2017-03-01 
2017-01-13 4 2017-03-01 
+0

是的,但只捕获一个快照日期。我正在创建一个循环并获取许多快照的数据集。 – Bob

+1

@Bob:这违背了SQL的基本设计。您需要将一些功能逻辑与此配对。这可能来自您的应用程序或存储过程中,但是使用纯SQL并不是一个好方法。像这样的纯SQL查询无法*循环*。 – Jacobm001

+0

我更新了我的响应,其中包含循环访问许多快照的代码 –