在一組記錄中查找「連續組」的一種方法是使用變量來跟蹤每行之間的差異,並開發將連續範圍組合在一起的分組。在下面的例子中,我用三個變量來跟蹤足夠的信息,生成組:
- @curEmployee - 跟蹤從過往紀錄,當前員工,並與當前記錄的員工相比,我們什麼時候知道的已切換到另一個員工,該員工自動變爲另一個分組
- @curEndDate - 跟蹤上一條記錄的最後結束日期,因此可以將其與當前記錄的開始日期進行比較,以查看當前記錄是否屬於與之前的記錄相同的「組」 - 也就是說,它是連續工作的一部分,與以前的記錄相同
- @curGroup - 這是關鍵變量e將行隔離成代表連續工作的獨立「組」。邏輯是,只有滿足以下兩個條件時,才應該將行視爲與前一行連續:兩行具有相同的員工編號,並且前一行的結束日期距離前一行不足21天當前行。
- 備註:您可能需要驗證邊緣條件,即相隔20/21/22天是否會被視爲連續使用,並調整下面的邏輯。
以下是計算這些組的示例查詢。需要注意以下幾點:變量賦值的順序很重要,因爲它們在select
列表中從上到下分配。我們首先需要分配@curGroup
,以便它仍然具有來自之前的記錄的@curEmployee
和@curEndDate
的值。其次,order by
條款對於確保當我們比較以前和當前記錄時非常重要,它們是彼此最接近的兩條記錄。如果我們以隨機順序查看記錄,它們可能會最終成爲單獨的組。
select
e.employee, e.`start date`, e.`end date`
,@curGroup :=
case when employee = @curEmployee
and @curEndDate + INTERVAL 21 DAY >= e.`start date`
then @curGroup
else @curGroup + 1
end as curGroup
,@curEmployee := employee as curEmployee
,@curEndDate := e.`end date` as curEndDate
from
employment e
JOIN (SELECT @curEmployee := 0, @curEndDate := NULL, @curGroup := 0) r
order by e.employee, e.`start date`
示例結果(DEMO) - 注意如何CURGROUP
停留在1
的前兩行,因爲他們是在彼此的21天,代表連續就業,而最後兩行得到認定爲獨立的組號:
| EMPLOYEE | START DATE | END DATE | CURGROUP | CUREMPLOYEE | CURENDDATE |
-------------------------------------------------------------------------------------------------------------------------------
| 1 | October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 | 1 | 1 | 2012-11-05 00:00:00 |
| 1 | November, 08 2012 00:00:00+0000 | January, 25 2013 00:00:00+0000 | 1 | 1 | 2013-01-25 00:00:00 |
| 2 | October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 | 2 | 2 | 2012-11-05 00:00:00 |
| 2 | November, 30 2012 00:00:00+0000 | January, 02 2013 00:00:00+0000 | 3 | 2 | 2013-01-02 00:00:00 |
現在我們已經確定的是連續工作的一部分記錄組,我們只需要按這些組號,找到的最小和最大日期範圍輸出:
select
employee,
min(`start date`) as `start date`,
max(`end date`) as `end date`
from (
select
e.employee, e.`start date`, e.`end date`
,@curGroup :=
case when employee = @curEmployee
and @curEndDate + INTERVAL 21 DAY >= e.`start date`
then @curGroup
else @curGroup + 1
end as curGroup
,@curEmployee := employee as curEmployee
,@curEndDate := e.`end date` as curEndDate
from
employment e
JOIN (SELECT @curEmployee := 0, @curEndDate := NULL, @curGroup := 0) r
order by e.employee, e.`start date`
) as T
group by curGroup
示例結果(DEMO):
| EMPLOYEE | START DATE | END DATE |
--------------------------------------------------------------------------------
| 1 | October, 01 2012 00:00:00+0000 | January, 25 2013 00:00:00+0000 |
| 2 | October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 |
| 2 | November, 30 2012 00:00:00+0000 | January, 02 2013 00:00:00+0000 |
太棒了!感謝您的答覆!這將是我第一次在select語句中積極使用已定義的變量。這個答案是美麗的代碼:-D – Schugs 2013-04-25 17:08:53