PostgreSQL: возвращает только одну таблицу, информация из двух таблиц в строки, когда информация в столбцах - PullRequest
0 голосов
/ 02 апреля 2019

В PostgreSQL у меня есть 2 таблицы с полями:

  • Working_date: id (autonumeric), employee_code (varchar (6)), working_date (date), working_hour (time),
  • Посещаемость: идентификатор (авто-числовой), код сотрудника (varchar (6)), дата-посещаемости (дата), час-посещаемости (время),

Пример данных:

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

Участники

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

В таблице «Посещаемость» есть несколько повторяющихся строк, потому что работник вводил посещаемость более одного раза. Например, 2015-07-09 было 2 раза (13:00:42, 13:00:47), когда пришло время выходить на старт. В этом случае следует получить только одну запись из 2-х, которые в настоящее время существуют. Другой случай 2015-07-09 - 10:33:31. Это записывается, когда сотрудник просит разрешения уйти с работы, а затем вернуться в этом случае в 13:00:42 / 13: 00: 47.

Есть ли способ получить working_date, working_hour с соответствующим значением посещаемости_hour в одной таблице только с чисто SQL-запросами (возможно, с некоторым типом подзапросов)? Пример:

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

Если это невозможно получить с помощью простого SQL-запроса, как это может быть достигнуто с помощью PL / PGSQL?

В настоящее время я делаю это с помощью PHP следующим образом:

  • Я запрашиваю поля "employee_code" и "working_date" из таблицы "working_date". Этот запрос выполняется между двумя датами: "from_date", "to_date".
  • Внутри «для утверждения» я консультируюсь с каждой строкой working_date со всеми строками working_hour: working_hour1, working_hour2, working_hour3, working_hour4. Для каждой строки запускается SQL-запрос. Для этого запроса я отправляю ему параметры employee_code и working_date.
  • Внутри вложенного «для выписки» с каждым рабочим часом я запускаю запрос к таблице «serveance_date» с параметрами: «employee_code», «working_date» и «working_hour». Он возвращает посещаемость_часа для каждого рабочего_часа.

Этот способ (вызов SELECTS из PHP с вложенным «для оператора») слишком медленный для получения и отображения информации. Я вижу процесс при его выполнении и процесс занимает 100% ЦП.

Надеюсь, я хорошо это объяснил.

Спасибо заранее за вашу помощь.

1 Ответ

0 голосов
/ 03 апреля 2019

Вы можете объединить эти таблицы по их датам и объединить время посещения в массив, сгруппировав по дате и коду сотрудника примерно так:

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

Вы можете использовать unnest () функция postgres для удаления этих массивов, но она поместит их в новые строки , а не в столбцы.Поместить их в отдельные столбцы сложно, потому что эти массивы, вероятно, не будут иметь одинаковую длину, и все строки должны иметь одинаковые столбцы.

Вот скрипка http://sqlfiddle.com/#!15/2a75c/7/0

...