Доступ PostgreSQL к ячейкам generate_series()

Я создаю серию дат через 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 с количеством часов, которые они работают над этой задачей в день.


person Thomas Pischulski    schedule 12.10.2012    source источник
comment
Каково определение результатов задачи?   -  person Craig Ringer    schedule 12.10.2012
comment
Я обновил свой пост определениями таблиц и некоторыми пояснениями.   -  person Thomas Pischulski    schedule 12.10.2012
comment
Я просто не могу понять, как остальные должны сочетаться друг с другом, в чем именно заключается проблема, с которой вы столкнулись, или для чего предназначены эти волшебные функции getstartdate и getenddate.   -  person Craig Ringer    schedule 12.10.2012
comment
В таблице задач хранятся задачи, и они могут быть определены в 4 различных типах (дата начала + минимальная продолжительность, дата окончания + минимальная продолжительность, дата начала + дата окончания, предшествующая + минимальная продолжительность). Третий тип — единственный тип, где я могу получить фиксированную дату начала и окончания. В остальных 3 случаях остальные столбцы, определяющие диапазон дат задач, имеют значение NULL. getstartdate/getenddate в основном возвращает мне даты, создавая avgs/quantiles через продолжительность в taskresults. Надеюсь хоть как-то понятно :/   -  person Thomas Pischulski    schedule 12.10.2012
comment
Я думаю, вам нужно упростить вашу схему до минимума, чтобы проиллюстрировать проблему, с которой вам нужна помощь, избавившись от всей посторонней и не относящейся к делу сложности.   -  person Craig Ringer    schedule 12.10.2012
comment
Смутное предположение выглядит примерно так: sqlfiddle.com/#!12/7aab5/5 но без демонстрационных данных, отсутствующих функций и т. д. сложно что-то сделать.   -  person Craig Ringer    schedule 12.10.2012
comment
И моя проблема в том, что я не могу соединить сгенерированный ряд дат с количеством рабочего времени сотрудников, когда они работают параллельно в произвольном количестве разных задач.   -  person Thomas Pischulski    schedule 12.10.2012
comment
Похоже, вам нужно общее табличное выражение (WITH) или использовать FROM (SELECT ...), используя generate_series в SELECT-списке, а затем отфильтровать и агрегировать его во внешнем запросе. Смотрите мой SQLFiddle.   -  person Craig Ringer    schedule 12.10.2012
comment
Хорошо, спасибо за помощь и попытку понять мою проблему, я проверю это.   -  person Thomas Pischulski    schedule 12.10.2012
comment
Если подумать, ты делаешь это трудным путем. Просто generate_series от min(startdate) до max(enddate) по всем интересующим значениям, CROSS JOIN на нем, затем используйте workday BETWEEN getstartdate(...) AND getenddate(...), чтобы отфильтровать те, которые выходят за пределы разумного диапазона.   -  person Craig Ringer    schedule 12.10.2012
comment
Не следует ли мне избегать использования функций в предложениях WHERE? Несмотря на то, что моя схема БД немного испорчена   -  person Thomas Pischulski    schedule 12.10.2012
comment
Если это медленные функции, было бы не идеально использовать их в предложении WHERE, нет. Вам нужно будет сделать несколько многоуровневых CTE или вложенных FROM (SELECT ...).   -  person Craig Ringer    schedule 12.10.2012
comment
Не волнуйтесь. Если вам не повезло после некоторого времени работы над ним, опубликуйте новый вопрос с помощью SQLFiddle, который показывает упрощенную схему с примерами данных, и опубликуйте созданную вручную таблицу ожидаемых результатов.   -  person Craig Ringer    schedule 12.10.2012
comment
Эй, я почти там, где хочу быть. Я сделал это, выполнив следующую таблицу: должны объединить его с сгенерированным рядом дат. Можете ли вы дать мне какой-либо совет по этому поводу? Ваше здоровье   -  person Thomas Pischulski    schedule 12.10.2012
comment
Хорошо, понял, запрос довольно неприятный, но имеет неплохую производительность, ваши советы мне очень помогли.   -  person Thomas Pischulski    schedule 12.10.2012


Ответы (1)


Вы можете JOIN в сгенерированном ряду, как и все остальное.

INNER JOIN generate_series(getstartdate(some arguments), getenddate(some arguments), interval '1 day') workday ON (...)

Условие соединения трудно определить, не зная, как хранятся ваши данные.

Кроме того, ваша структура данных странная. У сотрудников есть «задача»? n:1 сотрудники -> задача? Я не могу написать полный запрос, потому что я не понимаю структуру данных.

person Craig Ringer    schedule 12.10.2012