2012-11-28 69 views
2

我無法找到我的問題的答案,並且我不知道我的查詢是否正確,並且這可能是SQLite問題,請幫我解決問題。SQlite使用不同的「on」語句連接兩次相同的表

我在我的數據庫中的兩個表:

processTable {id} 
taskTable {id, processId, amount, done} 

有一個多到一的關係(一個進程可以分配多個任務)。 「數量」和「完成」是提供任務進度信息的整數值。如果「完成」> =「金額」,則任務完成。我需要查詢數據庫來獲取類似的東西:

+---------+-----------+------------+ 
| process | tasksDone | tasksCount | 
+---------+-----------+------------+ 
| 1  | 1   | 3   | 
+---------+-----------+------------+ 
| 2  | 2   | 5   | 
+---------+-----------+------------+ 

基礎上的數據,我在我的表:

processTable 
+----+ 
| id | 
+----+ 
| 1 | 
+----+ 
| 2 | 
+----+ 

tasksTable 
+----+-----------+--------+------+ 
| id | processId | amount | done | 
+----+-----------+--------+------+ 
| 1 | 1   | 10  | 10 | <- this task is done 
+----+-----------+--------+------+ 
| 2 | 1   | 15  | 5 | 
+----+-----------+--------+------+ 
| 3 | 1   | 80  | 5 | 
+----+-----------+--------+------+ 
| 4 | 2   | 25  | 0 | 
+----+-----------+--------+------+ 
| 5 | 2   | 60  | 60 | <- this task is done 
+----+-----------+--------+------+ 
| 6 | 2   | 30  | 15 | 
+----+-----------+--------+------+ 
| 7 | 2   | 40  | 40 | <- this task is done 
+----+-----------+--------+------+ 
| 8 | 2   | 100 | 50 | 
+----+-----------+--------+------+ 

所以,我寫此查詢:

SELECT processTable.id AS process, 
     COUNT(tasksTableDone.id) AS tasksDone, 
     COUNT(tasksTableAll.id) AS tasksCount 

FROM processTable 

LEFT JOIN tasksTable AS tasksTableAll 
    ON tasksTableAll.processId = processTable.id 

LEFT JOIN tasksTable AS tasksTableDone 
    ON tasksTableDone.processId = processTable.id 
      AND 
      tasksTableDone.done >= tasksTableDone.amount 

但我得到的是:

+---------+-----------+------------+ 
| process | tasksDone | tasksCount | 
+---------+-----------+------------+ 
| 1  | 3   | 3   | 
+---------+-----------+------------+ 
| 2  | 5   | 5   | 
+---------+-----------+------------+ 

我試圖在一次只運行一次連接的情況下運行查詢,並且一切正常。

查詢,只有第一個加入:

SELECT processTable.id AS process, 
     COUNT(tasksTableAll.id) AS tasksCount 

FROM processTable 

LEFT JOIN tasksTable AS tasksTableAll 
    ON tasksTableAll.processId = processTable.id 

Result: 
+---------+------------+ 
| process | tasksCount | 
+---------+------------+ 
| 1  | 3   | 
+---------+------------+ 
| 2  | 5   | 
+---------+------------+ 

查詢與第二隻加入:

SELECT processTable.id AS process, 
     COUNT(tasksTableDone.id) AS tasksDone 

FROM processTable 

LEFT JOIN tasksTable AS tasksTableDone 
    ON tasksTableDone.processId = processTable.id 
      AND 
      tasksTableDone.done >= tasksTableDone.amount 

Result: 
+---------+-----------+ 
| process | tasksDone | 
+---------+-----------+ 
| 1  | 1   | 
+---------+-----------+ 
| 2  | 2   | 
+---------+-----------+ 

如何使用這兩加入一個查詢中得到正確的結果?我知道,不是JOIN,我可以使用另一個SELECT,但我認爲它在性能意義上會更昂貴。

回答

3

您可以實現CASE語句的集合:

使用SUM()

SELECT p.id AS process, 
    sum(case when t.amount = t.done then 1 else 0 end) AS tasksDone, 
    count(p.id) AS tasksCount 
FROM processTable p 
LEFT JOIN tasksTable t 
    ON t.processId = p.id 
group by p.id 

版本請參閱SQL Fiddle with Demo

使用COUNT()版本:

SELECT p.id AS process, 
    count(case when t.amount = t.done then 1 else null end) AS tasksDone, 
    count(p.id) AS tasksCount 
FROM processTable p 
LEFT JOIN tasksTable t 
    ON t.processId = p.id 
group by p.id 

SQL Fiddle with Demo

編輯,您的評論後,您可以在選擇包裝這得到progress

select process, 
    tasksDone, 
    tasksCount, 
    (tasksDone/tasksCount) progress 
from 
(
    SELECT p.id AS process, 
    count(case when t.amount = t.done then 1 else null end) AS tasksDone, 
    count(p.id) AS tasksCount 
    FROM processTable p 
    LEFT JOIN tasksTable t 
    ON t.processId = p.id 
    group by p.id 
) src 
+2

您可以使用SQLite/MySQL的功能,TRUE = 1,FALSE = 0。因此'總和( case when t.amount = t.done then 1 else 0 end)'與sum(t.amount = t.done)相同' –

+0

@ypercube感謝那些信息,我不知道。我通常不在MySQL或SQLite中工作。 – Taryn

+0

這太棒了!它的功能就像魅力一樣,但還有一個問題:因爲您不使用JOIN,所以不能添加包含計算的進度值的另一列,例如:SELECT ...(tasksDone/tasksCount)AS progress' - 針對這個問題的解決方案? – Darrarski

相關問題