Я создаю серию дат через PostgreSQL generate_series(min, max)
следующим образом:
SELECT
generate_series(getstartdate(some arguments)
, getenddate(some arguments), interval '1 day')
FROM taskresults
getstartdate()
и getenddate()
возвращают дату начала и окончания данной задачи. У меня есть еще таблицы Employees(employeeid, taskid, worktime)
и Tasks(taskid, startdate, enddate)
.
Моя цель состоит в том, чтобы сгруппировать рабочее время сотрудников по дням из моей сгенерированной серии. Как я могу выполнить это соединение? Обратите внимание, что у меня нет прямого доступа к столбцам startdate
и enddate
в таблице Tasks
. Я могу получить доступ к датам только через упомянутые выше функции. Рабочее время указано в часах в день, поэтому я должен суммировать его через SUM()
для каждой задачи, над которой работает сотрудник, до указанной даты в серии. Проблема в том, что я не знаю, как получить доступ к дате в сгенерированной серии.
ИЗМЕНИТЬ
Структуры данных:
CREATE TABLE employees
(
employeeid serial NOT NULL,
firstname character varying(32),
lastname character varying(32),
qualification character varying(32),
incomeperhour numeric,
)
CREATE TABLE employeetasks
(
projectid integer,
taskid integer,
employeeid integer,
hoursperday real,
)
CREATE TABLE taskresults
(
simulationid integer,
taskid integer,
duration integer
)
CREATE TABLE tasks
(
projectid integer NOT NULL,
taskname character varying(32),
startdate character varying(32),
enddate character varying(32),
predecessor integer,
minduration integer,
maxduration integer,
taskid integer,
)
Некоторое объяснение:
Вся база данных предназначена для моделирования, поэтому сначала вы определяете расписание задач (в таблице tasks
), а затем запускаете моделирование, которое вставляет результаты в taskresults
. Как видите, я сохраняю только duration
в результатах, поэтому я могу получить доступ к диапазонам дат для каждой задачи только с помощью функций getstartdate
/getenddate
. Таблица employeetasks
в основном назначает сотрудников из таблицы employees
таблице task
с количеством часов, которые они работают над этой задачей в день.
WITH
) или использоватьFROM (SELECT ...)
, используяgenerate_series
вSELECT
-списке, а затем отфильтровать и агрегировать его во внешнем запросе. Смотрите мой SQLFiddle. - person Craig Ringer   schedule 12.10.2012generate_series
от min(startdate) до max(enddate) по всем интересующим значениям, CROSS JOIN на нем, затем используйтеworkday BETWEEN getstartdate(...) AND getenddate(...)
, чтобы отфильтровать те, которые выходят за пределы разумного диапазона. - person Craig Ringer   schedule 12.10.2012FROM (SELECT ...)
. - person Craig Ringer   schedule 12.10.2012