根据子记录的条件过滤出父记录

时间:2018-09-03 20:56:07

标签: sql sql-server tsql

我有两个带有伪模式的表,如下所示:

...SnapshotWithOptions

请注意,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(父表): 1-父级至少有一个在TaskPK状态下不是的子级记录 2-父级至少有一个子记录,其处于Completed状态,并且其完成日期已超过30天从今天开始。

我试图用Completed来写,但这并不完全正确:

GroupBy

3 个答案:

答案 0 :(得分:1)

我会为此使用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毫秒,否则结果可能令人惊讶。

答案 1 :(得分:1)

好吧,直接使用您的描述:

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()));

答案 2 :(得分:1)

我们也可以使用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()))