2017-03-06 51 views
1

我有2個表,任務表,其中一個任務的進度存儲mysql的:在一個子表計數的記錄,按日期

Tasks 
ID Description 
1 task1 
2 task2 
3 task3 
4 task4 
5 task5 

任務日誌

ID taskId dtTime  Status 
1 1  2016-01-01 new 
2 1  2016-02-10 in progress 
3 1  2016-03-03 closed 
4 2  2016-01-01 new 
5 2  2016-01-10 in progress 
6 2  2016-01-11 closed 
7 3  2016-01-01 new 
8 4  2016-01-01 new 
9 5  2016-01-01 new 
10 5  2016-01-01 in progress 
表「任務日誌」分組

一個任務可以有多個任務日誌記錄 現在我想要創建一個報告來顯示每個月「打開」的多少個任務(打開意味着他們沒有任務日誌記錄的狀態在該月「關閉」)在最近24個月。

所以我需要的是這樣的:

2016-01 4 
2016-02 4 
2016-03 3 

我相信這些應該是實際數字的查詢應導致

我掙扎編寫正確的查詢來做到這一點。我認爲我很接近,但在下面的查詢中,我正在計算任務日誌記錄,而不管我有多少個任務記錄記錄,我都要計算任務記錄。

select month(dtTime) month, year(dtTime) year, count(t.id) as number 
    from tasklog tl 
    join tasks t on t.id = taskId 
    where dtTime > DATE_ADD(now(), INTERVAL -2 YEAR) 
    and t.id not in ( 
     select id from tasklog tl1 
     where status in ('closed') 
     and month(tl1.dtTime) = month(tl.dtTime) 
     and year(tl1.dtTime) = year(tl.dtTime) 
    ) 
    group by month(dtTime), year(dtTime) 
    order by dtTime; 

任何建議如何我最好做到這一點?創建/填充表

代碼:

CREATE TABLE tasks 
    (`id` int, `description` varchar(5)) 
; 

INSERT INTO tasks 
    (`id`, `description`) 
VALUES 
    (1, 'task1'), 
    (2, 'task2'), 
    (3, 'task3'), 
    (4, 'task4'), 
    (5, 'task5') 
; 


CREATE TABLE tasklog 
    (`ID` int, `taskId` int, `dtTime` datetime, `Status` varchar(11)) 
; 

INSERT INTO tasklog 
    (`ID`, `taskId`, `dtTime`, `Status`) 
VALUES 
    (1, 1, '2016-01-01 00:00:00', 'new'), 
    (2, 1, '2016-02-10 00:00:00', 'in progress'), 
    (3, 1, '2016-03-03 00:00:00', 'closed'), 
    (4, 2, '2016-01-01 00:00:00', 'new'), 
    (5, 2, '2016-01-10 00:00:00', 'in progress'), 
    (6, 2, '2016-01-11 00:00:00', 'closed'), 
    (7, 3, '2016-01-01 00:00:00', 'new'), 
    (8, 4, '2016-01-01 00:00:00', 'new'), 
    (9, 5, '2016-01-01 00:00:00', 'new'), 
    (10, 5, '2016-01-01 00:00:00', 'in progress') 
; 

更新響應斯特凡諾賈尼尼

看來這兩種解決方案沒有得到我正確的結果。正確的結果應該是這樣,我相信:

2016-01 4 
2016-02 4 
2016-03 3 

查詢只給我:

1 2016 4 

如果我添加了獨特的,以我的查詢,我得到:

1 2016 5 
2 2016 1 
3 2016 1 

回答

1

我會與左連接

select month(tl.dtTime) month, year(tl.dtTime) year, count(t.id) as number 
    from tasks t 
    join tasklog tl 
    on t.id = tl.taskId and tl.status = 'new' 
    left join tasklog tl2 
    on t.id = tl2.taskId and month(tl.dtTime) = month(tl2.dtTime) and tl2.status = 'closed' 
    where dtTime > DATE_ADD(now(), INTERVAL -2 YEAR) 
    and tl2.taskId is null 
    group by month(tl.dtTime), year(tl.dtTime) 
    order by dtTime; 

編輯

...但你可能只需要在你的count

count(distinct t.id) 

編輯經過進一步的解釋添加distinct條款

我誤解了要求。這將做到這一點:

select distinct mm.month, count(distinct tl.taskId) 
from (select distinct month(dtTime) mm from tasklog) mm 
join tasklog tl 
on  mm.montId >= month(tl.dtTime) and tl.Status = 'new' 
left join 
     tasklog tl2 
on  mm.month >= month(tl2.dtTime) and tl2.Status = 'closed' and tl.taskId = tl2.taskId 
where tl2.taskId is null 
group by mm.month 
order by 1; 

第一次加入每個月加入到該月份開放的所有任務。在第二次加入時,如果任務在該月或之前關閉,則爲每個月/ taskId賦予一個值。從這裏您可以僅過濾每個月的打開任務,過濾沒有此值的行。

您必須添加年份,並可能會細化連接子句,但是您提供的查詢數據的示例數據是完全正確的。

+0

看到我的問題的回答(大的評論) – ErikL

+0

對不起,我誤解你的要求。我編輯了一個解決方案,應該正是你需要的答案。 –

+0

感謝Stefano,這個查詢的確給了我想要的結果,花了我一段時間來弄清楚發生了什麼,但現在我明白了。看起來像一個聰明的解決方案,謝謝! – ErikL

0

這是我結束了:

select distinct mm.year as year, 
       mm.month as month, 
       count(distinct tl.taskId) number 
from (select distinct month(dtTime) month , year(dttime) year from tasklog) mm 
join tasklog tl 
on  mm.month >= month(tl.dtTime) and mm.year >= year(tl.dtTime) and tl.Status !='closed' 
left join 
     tasklog tl2 
on  mm.month >= month(tl2.dtTime) and mm.year >= year(tl2.dtTime) and tl2.Status = 'closed' and tl.taskId = tl2.taskId 
where tl2.taskId is null 
group by mm.month 
order by 1; 
相關問題