In PostgreSQL I have 2 tables with fields:
id
(autonumeric), employee_code
(varchar (6)), working_date
(date), working_hour
(time), id
(autonumeric), employee_code
(varchar (6)), attendance_date
(date), attendance_hour
(time),Data example:
Working_date
ID | employee_code | working_date | working_hour
1 | 12345 | 2015-07-09 | 08:00
2 | 12345 | 2015-07-09 | 13:00
3 | 12345 | 2015-07-09 | 14:00
4 | 12345 | 2015-07-09 | 17:00
5 | 12345 | 2015-07-10 | 08:00
6 | 12345 | 2015-07-10 | 13:00
7 | 12345 | 2015-07-10 | 14:00
8 | 12345 | 2015-07-10 | 17:00
9 | 12345 | 2015-07-11 | 08:00
10 | 12345 | 2015-07-11 | 13:00
11 | 12345 | 2015-07-11 | 14:00
12 | 12345 | 2015-07-11 | 17:00
13 | 12345 | 2015-07-12 | 08:00
14 | 12345 | 2015-07-12 | 13:00
15 | 12345 | 2015-07-12 | 14:00
16 | 12345 | 2015-07-12 | 17:00
17 | 12345 | 2015-07-13 | 08:00
18 | 12345 | 2015-07-13 | 13:00
19 | 12345 | 2015-07-13 | 14:00
20 | 12345 | 2015-07-13 | 17:00
Attendance
ID | employee_code | attendance_date | attendance_hour
1 | 12345 | 2015-07-09 | 07:56:53
2 | 12345 | 2015-07-09 | 10:33:31
3 | 12345 | 2015-07-09 | 13:00:42
4 | 12345 | 2015-07-09 | 13:00:47
5 | 12345 | 2015-07-09 | 13:30:21
6 | 12345 | 2015-07-09 | 17:00:01
7 | 12345 | 2015-07-10 | 07:48:35
8 | 12345 | 2015-07-10 | 12:15:20
9 | 12345 | 2015-07-10 | 13:58:42
10 | 12345 | 2015-07-10 | 17:02:00
11 | 12345 | 2015-07-11 | 08:06:46
12 | 12345 | 2015-07-11 | 12:00:01
13 | 12345 | 2015-07-11 | 13:52:01
14 | 12345 | 2015-07-11 | 17:05:08
15 | 12345 | 2015-07-12 | 07:55:02
16 | 12345 | 2015-07-12 | 12:03:22
17 | 12345 | 2015-07-12 | 13:37:40
18 | 12345 | 2015-07-12 | 17:05:01
19 | 12345 | 2015-07-13 | 07:54:25
20 | 12345 | 2015-07-13 | 10:44:15
21 | 12345 | 2015-07-13 | 13:59:21
22 | 12345 | 2015-07-13 | 17:01:17
In table "Attendance" there are some repetitive rows because employee entered attendance more than once. For example on 2015-07-09 there are 2 attendance times (13:00:42, 13:00:47) when it is time to go out for lunch. In this case, I should get only one of the two records.
The other case on 2015-07-09 there is 10:33:31. It is recorded when the employee asks permission to leave work and then returns in this case at 13:00:42 / 13:00:47.
Is there a way for getting working_date
, working_hour
with its respective attendance_hour
in one table with only pure SQL queries (maybe some type of subqueries)?
Example:
ID | employee_code | working_date | working_hour1 | attendance_time_1 | working_hour2 | attendance_time_2 | working_hour3 | attendance_time_3 | working_hour4 | attendance_time_4
1 | 12345 | 2015-07-09 | 08:00 | 07:56:53 | 13:00:00 | 13:00:42 or 13:00:47 | 14:00 | 13:30:21 | 17:00 | 17:00:01
2 | 12345 | 2015-07-10 | 08:00 | 07:48:35 | 13:00:00 | 12:15:20 | 14:00 | 13:58:42 | 17:00 | 17:02:00
3 | 12345 | 2015-07-11 | 08:00 | 08:06:46 | 13:00:00 | 12:00:01 | 14:00 | 13:52:01 | 17:00 | 17:05:08
4 | 12345 | 2015-07-12 | 08:00 | 07:55:02 | 13:00:00 | 12:03:22 | 14:00 | 13:37:40 | 17:00 | 17:05:01
5 | 12345 | 2015-07-13 | 08:00 | 07:54:25 | 13:00:00 | 10:44:15 | 14:00 | 13:59:21 | 17:00 | 17:01:17
In case it is not possible to get it with pure SQL querie, how can it achieved with maybe PL/PGSQL?
Currently I make it with PHP like this:
employee_code
and working_date
fields from working_date
table. This query is run between 2 dates: from_date
, to_date
.working_hour1
, working_hour2
, working_hour3
, working_hour4
. For every row is run an SQL query. For this query I send it employee_code
and working_date
parameters.working_hour
, I run a query to "attendance_date" table with parameters: employee_code
, working_date
and working_hour
. It returns the attendance_hour
for every working_hour
.This way (calling SELECTS from PHP with nested "for statement") is too slow for getting and showing the info. I see the process when executing it and process takes 100% of CPU.
You can join those tables on their dates and aggregate the attendance times into an array by grouping by date and employee_code somewhat like this:
SELECT
w.employee_code,
w.working_date,
array_agg(distinct(w.working_hour)) working_hours,
array_agg(distinct(a.attendance_hour)) attendance_hours
FROM Working_date w
LEFT JOIN attendance a
ON (w.working_date = a.attendance_date)
GROUP BY w.working_date, w.employee_code
ORDER BY w.working_date
You could use the unnest() function of postgres to unnest those arrays, but it will put them into new rows not columns. Putting them into separate columns is difficult because those arrays probably won't be the same length and all rows have to have the same columns.
Heres a fiddle http://sqlfiddle.com/#!15/2a75c/7/0
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.