sql - count列取决于父母还是孩子

时间:2013-01-15 17:35:49

标签: sql-server tsql

我希望在某些条件下得到列的总和,即取决于列是具有子任务的父级还是只是没有子任务的父级。如果任务是具有子任务的父项,我只需要子任务的“完整”列的总和。如果任务只是父​​级,我只需要父级的完整列的总和。 - 但仅限于任务(父或子)都与同一用户相关。

E.g。在以下示例表中:

UserID | Parent_TaskID | TaskID  | Complete
------ | ------------- | ------  | --------
435    | 149329        | 161280  |   1
435    | 149330        | 210717  |   2
435    | 149330        | 228100  |   3
435    | 156991        | 149330  |   1
169    | 458764        | 546540  |   2
169    | 456842        | 546541  |   2
169    | 456842        | 458764  |   0

TaskID 149330是有孩子的父母210717& 228100因此149330的该列的计数为5,即忽略父级的完整列。 161280是父母,所以只返回0。 546540是458764的子任务,因此458764的总和为2.

所以我认为我的结果应该是这样的:

TaskID  |  Sum_complete
------- |  ------------
161280  |  1
149330  |  5
546541  |  2
458764  |  2

任何想法如何做到这一点?

我在SqlFiddle http://sqlfiddle.com/#!2/8295f

创建了一个表

谢谢,

我可以使用以下内容获取父母:

select t.taskID, t.Parent_taskID, t.userID, t.complete 
from task t
where t.Parent_taskID not in (
    select tp.taskID
    from task tp
    where tp.userID = t.userID 
)

2 个答案:

答案 0 :(得分:3)

根据您的描述,我认为您要求以下内容(使用问题中的示例数据):

编辑:替换查询以从结果集中删除子项。

declare @Task as Table
  ( UserId varchar(6), Parent_TaskId varchar(13), TaskId varchar(6), Complete integer );

INSERT INTO @Task ( UserId, Parent_TaskId, TaskId, Complete ) VALUES
    ('435', '149329', '161280', 1 ),
    ('435', '149330', '210717', 2 ),
    ('435', '149330', '228100', 3 ),
    ('435', '156991', '149330', 1 ),
    ('169', '458764', '546540', 2 ),
    ('169', '456842', '546541', 2 ),
    ('169', '456842', '458764', 0 );

; with QualifiedTasks as (
  select UserId, TaskId, Parent_TaskId, Complete,
    case when exists ( select 42 from @Task where Parent_TaskId = O.TaskId ) then 1 else 0 end as Parent,
    case when exists ( select 42 from @Task where O.Parent_TaskId = TaskId ) then 1 else 0 end as Child, -- Unused, but here for completeness.
    case when not exists ( select 42 from @Task where Parent_TaskId = O.TaskId or O.Parent_TaskId = TaskId ) then 1 else 0 end as Loner  
    from @Task as O )
  select L.TaskID, Sum( Coalesce( R.Complete, L.Complete ) ) as Sum_Complete
    from QualifiedTasks as L left outer join
      QualifiedTasks as R on R.Parent_TaskId = L.TaskId and R.UserId = L.UserId
    where L.Parent = 1 or L.Loner = 1
    group by L.TaskId;

一些明显的优化浮现在脑海中。 ParentChildLoner列是多余的,三者中的任何一个都可以删除。 Parent可以在摘要查询中确定Max( R.Complete ) is not NULLChildLoner的一个聪明伎俩目前逃脱了我。

答案 1 :(得分:0)

这应该有用(虽然您在问题上发布的数据与小提琴上的数据不同):

SELECT ISNULL(B.taskId,A.TaskId) TaskId, SUM(A.Complete) Complete
FROM Task A
LEFT JOIN Task B
ON A.Parent_TaskID = B.taskId
GROUP BY ISNULL(B.taskId,A.TaskId)