2017-06-29 121 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

我更新了我的響應,其中包含循環訪問許多快照的代碼 –