2013-01-15 50 views
2

我期望在某些條件下獲得某列的總和,即取決於某列是具有子任務的父母,還是僅具有沒有子任務的父母。如果任務是具有子任務的父項,則只需要子任務的「完成」列的總和。如果一項任務只是一個家長,我只想要父母的完整列的總和。 - 但只限於任務(父母或子女)都與同一用戶有關。SQL - 根據父母或子女是否計數列

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 
) 
+0

[你有什麼試過](http://whathaveyoutried.com)? – HABO

+0

你用tsql標記了你的問題,但你的小提琴是用於MySQL的。你使用的是什麼RDBMS和版本? – Lamak

+0

哦,對不起,我正在使用SQL Server ... 2005 – thegunner

回答

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; 

有一些明顯的優化可以想到。 Parent,ChildLoner列是多餘的,三者中的任何一個都可以被消除。可以通過Max(R.Complete) is not NULL在總結查詢中確定Parent。目前,ChildLoner的一個聰明的伎倆逃脫了我。

+0

嗨,謝謝你的回答,但只有4個主要任務:161280,149330,546541,458764 ..其餘全部都有主鍵在任務ID列表中。 210717和228100是子任務149300. 546540是458764的子任務。 – thegunner

+0

@thegunner - 明白了,只有父母和孤兒輸出。我已經相應地更新了答案。 – HABO

+0

不錯的作品@Habo! – thegunner

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) 
+0

如此接近......似乎無法得到isnull工作,但如果我使用coalesce而不是isnull並將ON A.Parent_TaskID更改爲ON A.Parent_TaskID = B.taskId和A.UserID = B.UserID,那麼它幾乎可行! .. – thegunner

+0

@thegunner:通過只添加一個外連接和一個WHERE條件,你可以使這個解決方案工作,我想:'... LEFT JOIN任務C ON A.TaskId = C.Parent_taskId WHERE C.TaskId IS NULL ...'。 –