1 (edited by savage 2014-09-28 14:34:49)

Topic: [Решено] SELECT с отбором по макс и мин из отфильтрованных записей

День добрый.
Столкнулся с такой проблемой:
1. Есть 2 таблицы:
а) таблица Tasks с Задачами (название Задачи, дата старта, дата финиша плановая, дата финиша фактическая)
б) таблица SubTasks с подзадачами (название Подзадачи, дата старта, дата финиша плановая, дата финиша фактическая) . Подзадачи, собственно являются детализацией Задачи.
2. Работает стандартная процедура - на форме вывода информации при выборе в верхнем гриде Задачи, в нижнем гриде можно увидеть список ее подзадач
3. Собственно, вопрос №1:
я решил автоматизировать проставление в информации о Задаче следующих полей:
дата старта
дата финиша плановая
дата финиша фактическая
Делается это на основании данных о подзадачах:
дата старт - минимальное значение в соответствующем поле Подзадач ,входящих в конкретную Задачу, забивается в конкретный DateTimePicker,
аналогично сделано с "дата финиша плановая" - только через максимальное значение
Код:

 procedure AddSubTask_BtSubTaskOK_OnAfterClick (Sender: string);
begin
      // выбор максимальной и минимальных дат в таблице подзадач и вставка их в даты начала и окончания конкретной Задачи
      NewTask.DateTimePicker3.DateTime:=  SQLDateTimeToDateTime(SQLExecute('SELECT min(start_pf) FROM SubTasks;'));
      NewTask.DateTimePicker1.DateTime:=  SQLDateTimeToDateTime(SQLExecute('SELECT max(finish_plan) FROM SubTasks;'));
end;

Проблема - данный скипт работает со всем списком подзадач в таблице SubTasks, т.е. со всеми подзадачами всех Задач, а мне необходимо, чтобы он работал только с конкретными, относящимися только к конкретной Задаче.
Получается, что при сохранении в Task конкретной задачи сохраняется данные по датам макс и мин среди всех записей SubTasks, а не тех, которые принадлежат именно этой Задаче. Как реализовать фильтр?

вопрос №2:
не знаю, как лучше реализовать автоматическое проставление в конкретном поле Task  "дата финиша фактическая". Дело в том, что данная дата должна проставляться в соответствующем DateTimePicker только тогда, когда закончится выполнение всех подзадач данной Задачи.  Т.е. должно выполняться несколько условий:
1. все записи поля finish_fact, имеющие отношение к конкретной Задаче, в таблице SubTasks должны иметь дату,
2. в таблицу Tasks попадает максимальная дата из всех этого поля (опять-таки, отбор только по подзачачам конкретной Задачи).

PS немного сумбурно получилось, если необходимо прикреплю проект

2 (edited by savage 2014-09-28 15:36:21)

Re: [Решено] SELECT с отбором по макс и мин из отфильтрованных записей

Общий код сейчас представляет собой следующее:

procedure AddSubTask_BtSubTaskOK_OnAfterClick (Sender: string);
var
  i,c, q: integer;

begin
      // выбор максимальной и минимальных дат в таблице подзадач и вставка их в даты начала и окончания конкретной Задачи
      NewTask.DateTimePicker3.DateTime:=  SQLDateTimeToDateTime(SQLExecute('SELECT min(start_pf) FROM SubTasks;'));
      NewTask.DateTimePicker1.DateTime:=  SQLDateTimeToDateTime(SQLExecute('SELECT max(finish_plan) FROM SubTasks;'));
     //проверка на все проставленные даты фактического окончания подзадач и если это правда, то выбор махимальной с переносом в соответсвующее поле Задачи
     q := 0;
     c := NewTask.TabGrSubTasks.RowCount;
     for i := 0 to c do
         if NewTask.TabGrSubTasks.Cells[4, i] <> '' then Inc(q);


    // begin
     if c = q then
      begin
       NewTask.DateTimePicker2.DateTime:= SQLDateTimeToDateTime(SQLExecute('SELECT max(finish_fact) FROM SubTasks;'));
      end;
end;

Таким образом, не решен 1 вопрос:
- как ограничить записи (подзадачи) SubTask только теми, которые имеют отношение к конкретным записям Tasks (задачам)?

3 (edited by savage 2014-09-28 20:49:36)

Re: [Решено] SELECT с отбором по макс и мин из отфильтрованных записей

Решил через получение из Tasks  id названия задачи (поле task_name)
Код:

procedure NewTask_TabGrSubTasks_OnChange (Sender: string);
var
  i,c,q,idTask : integer;
  sDate: string;
begin
      // получение id Задачи из таблицы Tasks
      idTask:= SQLExecute('SELECT id FROM Tasks WHERE Tasks.Task_name LIKE "' + NewTask.Edit1.Text  + '";');

      // выбор максимальной и минимальных дат в таблице подзадач и вставка их в даты начала и окончания конкретной Задачи
      sDate := SQLExecute('SELECT min(start_pf) FROM SubTasks WHERE SubTasks.id_Tasks = "' + IntToStr(idTask)  + '";');
      if sDate <> '' then NewTask.DateTimePicker3.DateTime :=  SQLDateTimeToDateTime(sDate);

      sDate := SQLExecute('SELECT max(finish_plan) FROM SubTasks WHERE SubTasks.id_Tasks = "' + IntToStr(idTask)  + '";');
      if sDate <> '' then NewTask.DateTimePicker1.DateTime:=  SQLDateTimeToDateTime(sDate);


     //проверка на все проставленные даты фактического окончания подзадач и если это правда, то выбор махимальной с переносом в соответсвующее поле Задачи
     q := 0;
     c := NewTask.TabGrSubTasks.RowCount;
     for i := 0 to c do
         if NewTask.TabGrSubTasks.Cells[4, i] <> '' then Inc(q);


     if c = q then
      begin
       sDate := SQLExecute('SELECT max(finish_fact) FROM SubTasks WHERE SubTasks.id_Tasks = "' + IntToStr(idTask)  + '";');
       if sDate <> '' then NewTask.DateTimePicker2.DateTime:= SQLDateTimeToDateTime(sDate);
       NewTask.CheckBox1.State := cbUnChecked;
      end else
       begin
         NewTask.DateTimePicker2.Checked := False;
         NewTask.CheckBox1.State := cbChecked;
       end;
end;