简体   繁体   English

当信息在列中时,仅将一个表信息从两个表返回到行中

[英]Return in only one table info from two tables into rows when info is in columns

In PostgreSQL I have 2 tables with fields:在 PostgreSQL 中,我有 2 个带有字段的表:

  • Working_date: id (autonumeric), employee_code (varchar (6)), working_date (date), working_hour (time), Working_date: id (自动数字)、 employee_code (varchar(6))、 working_date (日期)、 working_hour (时间)、
  • Attendance: id (autonumeric), employee_code (varchar (6)), attendance_date (date), attendance_hour (time),出勤: id (自动数字), employee_code (varchar(6)), attendance_date日期(日期), attendance_hour时间(时间),

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.例如在 2015-07-09 有 2 个出勤时间(13:00:42, 13:00:47)到了出去吃午饭的时间。 In this case, I should get only one of the two records.在这种情况下,我应该只得到两条记录中的一条。

The other case on 2015-07-09 there is 10:33:31. 2015-07-09 的另一个案例是 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.当员工请求离开工作的许可,然后在这种情况下在 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)?有没有办法只使用纯 SQL 查询(可能是某种类型的子查询)在一个表中获取working_dateworking_hour及其各自的attendance_hour时间?

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?如果无法通过纯 SQL 查询获得它,那么如何通过 PL/PGSQL 实现?

Currently I make it with PHP like this:目前我用 PHP 制作它是这样的:

  • I query employee_code and working_date fields from working_date table.我从working_date表中查询employee_codeworking_date字段。 This query is run between 2 dates: from_date , to_date .此查询在 2 个日期之间运行: from_dateto_date
  • Inside a "for statement" I consult with every row of working_date all the working_hour rows: working_hour1 , working_hour2 , working_hour3 , working_hour4 .在“for 语句”中,我咨询了working_date 的每一行所有working_hour 行: working_hour1working_hour2working_hour3working_hour4 For every row is run an SQL query.对每一行运行一个 SQL 查询。 For this query I send it employee_code and working_date parameters.对于这个查询,我向它发送了employee_codeworking_date参数。
  • Inside a nested "for statement", with every working_hour , I run a query to "attendance_date" table with parameters: employee_code , working_date and working_hour .在嵌套的“for 语句”中,每使用working_hour ,我都会使用参数对“attendance_date”表运行查询: employee_codeworking_dateworking_hour It returns the attendance_hour for every working_hour .它返回每个working_hourattendance_hour时间。

This way (calling SELECTS from PHP with nested "for statement") is too slow for getting and showing the info.这种方式(使用嵌套的“for 语句”从 PHP 调用 SELECTS)对于获取和显示信息来说太慢了。 I see the process when executing it and process takes 100% of CPU.我在执行它时看到了进程,进程占用了 100% 的 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.您可以使用 postgres 的unnest()函数来取消嵌套这些数组,但它会将它们放入新而不是列中。 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这是一个小提琴http://sqlfiddle.com/#!15/2a75c/7/0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM