2016-10-12 17 views
1

我有一個包含employee_id,日期和打卡時間的出席表。在Postgres中爲特定範圍內的日期系列的員工出席

Emp_Id  PunchTime 
101  10/10/2016 07:15 
101  10/10/2016 12:20 
101  10/10/2016 12:50 
101  10/10/2016 16:31 
102  10/10/2016 07:15 

在這裏我只有工作日的日期。我想獲得一系列給定日期的員工的出席名單。我也需要一天。結果應該像下面

date  | day  |employee_id | Intime   |  outtime  | 
2016-10-09 | sunday | 101  |     |     | 
2016-10-10 | monday | 101  | 2016-10-10 7:15AM |2016-10-10 4:31 PM | 

回答

0

可以生成日期的列表,然後做外連接它們:

下顯示所有天在十月:

select d.date, a.emp_id, 
     min(punchtime) as intime, 
     max(punchtime) as outtime 
from generate_series(date '2016-10-01', date '2016-11-01' - 1, interval '1' day) as d (date) 
    left join attendance a on d.date = a.punchtime::date 
group by d.date, a.emp_id; 
order by d.date, a.emp_id; 

正如你想要每天的第一個和最後一個時間戳,可以使用簡單的group by查詢完成。

然而,這將不會重複emp_id爲非存在的日子。

+0

我怎麼能不斷產生棗系列,而不缺少之間的任何日期?如果在任何特定日期沒有日期,它應該是空白以外的日期。例如,如果我在星期天有假期,那麼我的出勤不會在那裏,在這種情況下,我需要顯示空白,但日期和日期應該在那裏。 –

+0

@MohammedNisar:'generate_series()'函數完全如此。我將在2016年10月1日和2016年1月1日之間每天生成一行。您可以使用該動態來生成存儲在考勤中的第一天和最後一天之間的所有日期。 –

0

類似下面的內容會生成一個日期範圍列表(起始和結束的時間範圍是在您的打卡時間表中找到的),包括員工和銀泰,每個​​人的外出時間。這裏檢查SQL小提琴:

http://sqlfiddle.com/#!15/d93bd/1

WITH RECURSIVE minmax AS 
(
    SELECT MIN(CAST(time AS DATE)) AS min, MAX(CAST(time as DATE)) AS max 
    FROM emp_time 
), 
dates AS 
(
    SELECT m.min as datepart 
    FROM minmax m 
    RIGHT JOIN emp_time e ON m.min = CAST(e.time as DATE) 
    UNION ALL 
    SELECT d.datepart + 1 FROM dates d, minmax mm 
    WHERE d.datepart + 1 <= mm.max 
) 
SELECT d.datepart as date, e.emp, MIN(e.time) as intime, MAX(e.time) as outtime FROM dates d 
LEFT JOIN emp_time e ON d.datepart = CAST(e.time as DATE) 
GROUP BY d.datepart, e.emp 
ORDER BY d.datepart; 
+0

謝謝..............根據我的數據庫結構進行了一些小的修改後,它爲我工作..非常感謝.... –

相關問題