2011-02-25 43 views
3

我怎麼能指望連續的時間框架

我的數據是這樣的:SQL數超過已知週期不同的時段

Id| Em_Name|Em_Reg_Date 
-------------------------------- 
1 | John |2010-03-30 00:00:00 
1 | John |2010-03-31 00:00:00 
2 | Marc |2010-10-26 00:00:00 
2 | Marc |2010-10-27 00:00:00 
2 | Marc |2010-10-28 00:00:00 
2 | Marc |2010-10-29 00:00:00 
2 | Marc |2010-12-16 00:00:00 
2 | Marc |2010-12-17 00:00:00  
2 | Marc |2010-12-20 00:00:00 
2 | Marc |2010-12-21 00:00:00 
2 | Marc |2010-12-22 00:00:00 
3 | Paul |2010-02-25 00:00:00 
3 | Paul |2010-02-26 00:00:00 
3 | Paul |2010-12-13 00:00:00 
3 | Paul |2010-12-14 00:00:00 
3 | Paul |2010-12-15 00:00:00 
-------------------------------- 

的時間框架是連續的時間段。
例如保羅有以下兩(2)時限

FRAME 1 FROM 2010-02-25 00:00:00 to 2010-02-26 00:00:00 
FRAME 2 FROM 2010-12-13 00:00:00 to 2010-12-15 00:00:00 

所以,結果應該是這樣的

1 John 1 
2 Marc 3 
3 Paul 2 

的問題是:我需要計算每個員工的時間框架。

這裏的問題在於,我需要隔離連續時間幀來計數它們。我甚至嘗試了一個聲明遊標(可以工作,但我必須將數據存儲在臨時表中)並且我希望這是一個「簡單的」sql語句 使用max查找僅適用於一個幀的開始日期。你找不到最大的第二/第三幀。

有沒有人有新的想法?

+0

RDBMS是什麼?哪個版本? – RichardTheKiwi 2011-02-25 13:02:08

+0

MS SQL SERVER 2008 – 2011-02-25 13:06:59

+0

我會試一試 – 2011-02-25 13:09:41

回答

2

的SQL Server 2005+

select em_name, COUNT(distinct startdate) 
from 
(
    select *, startdate = em_reg_date - ROW_NUMBER() over (
     partition by em_name order by em_reg_date) +1 
    from tbl 
) X 
group by Em_Name 

甲骨文,DB2還支持ROW_NUMBER(),但你需要一些變化來計算STARTDATE

+0

由於週末造成的間隙導致無法完全工作 – 2011-02-25 14:23:45

+0

您可能希望在您的問題中添加該問題(您不會說週末「不計算」)。我會看看我的答案也在重新... – MatBailie 2011-02-25 14:33:02

2

我不知道的對ID的原因, em_name字段,所以我會把它看作是ID足夠單獨使用。

我使用的邏輯就是這樣...一個組可以用組中的最後一個條目表示。最後一個條目只是一個條目,在第二天沒有匹配的條目。

如果存在(ID,Em_Reg_Date)的索引,這應該是相當快的。

SELECT 
    ID, 
    COUNT(*) 
FROM 
    your_table [source] 
WHERE 
    NOT EXISTS (
       SELECT 
       * 
       FROM 
       your_table 
       WHERE 
       Em_Reg_Date = [source].Em_Reg_Date + 1 
       AND ID = [source].ID 
      ) 
GROUP BY 
    ID 


編輯

這改變了邏輯看「到下一個星期一」如果當前記錄是週五,週六或週日。

SET DATEFIRST 1 -- This just ensures that Monday is counted as Day 1 

SELECT 
    ID, 
    COUNT(*) 
FROM 
    your_table [source] 
WHERE 
    NOT EXISTS (
       SELECT 
       * 
       FROM 
       your_table 
       WHERE 
       ID = [source].ID 
       AND Em_Reg_Date <= [source].Em_Reg_Date + CASE WHEN DATEPART(weekday, [source].Em_Reg_Date) >= 5 THEN 8 - DATEPART(weekday, [source].Em_Reg_Date) ELSE 1 END 
       AND Em_Reg_Date > [source].Em_Reg_Date 
      ) 
GROUP BY 
    ID 
+0

這應該適用於幾乎所有的RDBMS – MatBailie 2011-02-25 13:17:15

1
SELECT Id, Name, COUNT(Id) 
FROM (
    SELECT Id, Name 
    FROM `<your_table_name>` 
    GROUP BY Name, MONTH(Em_Reg_Date) 
    ) as X 
GROUP BY Id 

測試在MySQL 5.0.7

+1

這當然不會得到與OP給出的樣本相同的結果。 (Marc在12月有2個'相框') – MatBailie 2011-02-25 14:17:49

+0

哦!你是對的!我的解決方案不會工作:( – 2011-02-25 14:26:29

相關問題