Фильтрация родительских записей на основе условий дочерних записей - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть две таблицы с псевдо-схемой, подобной этой:

CREATE TABLE Task(TaskPK INT)

CREATE TABLE TaskDetails(TaskDetailsPK INT, TaskPK INT, CompleteDate DATETIME NULL, TaskDetailName CHAR(30) , Status CHAR(10))

Обратите внимание, что таблица TaskDetails имеет столбец CompleteDate, который также может быть NULL, а также столбец Status имеет несколько жестко закодированных значений, таких как «Завершено», «Отменено», «В процессе» , "Ожидание" ....

Я хочу написать запрос для поиска TaskPK (родительская таблица) в двух случаях: 1- Родитель имеет по крайней мере одну дочернюю запись, которая не в статусе Completed 2- Родитель имеет по крайней мере одну дочернюю запись, которая равна в Completed Статус И дата его завершения имеет не старше 30 дней с сегодняшнего дня.

Я пытался написать это с GroupBy, но это не совсем правильно:

select td.TaskPK from TaskDetail td
where ( td.CurrentStatus = 'Complete')
Group By td.TaskPK
Having Min(CompleteDate ) >= DATEADD(day, -30, GETDATE())

Ответы [ 3 ]

0 голосов
/ 04 сентября 2018

Ну, используя ваше описание напрямую:

SELECT 
    TaskPK 
  FROM 
    Task T
  WHERE
    EXISTS (SELECT 1 FROM TaskDetails TD WHERE TD.TaskPK = T.TaskPK AND Status <> 'Completed')
    OR
    EXISTS (SELECT 1 FROM TaskDetails TD WHERE TD.TaskPK = T.TaskPK AND Status = 'Completed' AND CompleteDate >= DATEADD(DAY, -30, GetDate()));
0 голосов
/ 04 сентября 2018

Мы также можем достичь требуемых результатов, используя INNER JOIN ... пожалуйста, проверьте код ниже ...

  SELECT T.TaskPK
  FROM TASK T
  INNER JOIN TaskDetails TD
  ON T.TaskPK = TD.TaskPK
  WHERE (TD.[Status]!= 'Completed') OR (TD.[Status] = 'Completed' AND TD.CompleteDate > 
  DATEADD(DD,-30,GETDATE()))
0 голосов
/ 04 сентября 2018

Я бы использовал EXISTS для этого.

SELECT t.taskpk
       FROM task t
       WHERE EXISTS (SELECT *
                            FROM taskdetails td
                            WHERE td.taskpk = t.taskpk
                                  AND td.status <> 'Completed')
              OR EXISTS (SELECT *
                                FROM taskdetails td
                                WHERE td.taskpk = t.taskpk
                                      AND td.status = 'Completed'
                                      AND td.completedate >= dateadd(day, -30, convert(date, getdate())));

Я не уверен, должны ли оба условия быть верными или только хотя бы одно из них. В первом случае вам придется изменить OR между двумя EXISTS на AND.

Я также опустил getdate() до date, так что он теряет свою временную составляющую. Если вы действительно не имеете в виду 30 дней = 30 * 24 * 60 * 60 * 1000 мс, иначе результаты могут быть неожиданными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...