2

質問に対する答えが見つかりませんでした。クエリが正しいかどうかわかりません。これは SQLite の問題である可能性があります。問題の解決を手伝ってください。

データベースに 2 つのテーブルがあります。

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

多対 1 の関係があります (1 つのプロセスに複数のタスクを割り当てることができます)。「金額」と「完了」は、タスクの進捗情報を提供する整数値です。"done" >= "amount" の場合、タスクは完了です。そのようなものを取得するには、データベースにクエリを実行する必要があります。

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

一度に 1 つの結合のみでクエリを実行しようとしましたが、すべてがうまく機能していました。

最初の結合のみを使用したクエリ:

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

2 番目の結合のみを使用したクエリ:

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

この 2 つの結合を 1 つのクエリ内で使用して適切な結果を得るにはどうすればよいですか? JOIN の代わりに別の SELECT を使用できることはわかっていますが、パフォーマンスの意味でより高価になると思います。

4

1 に答える 1

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 を参照してください

使用するバージョン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 を参照してください

編集、コメントの後、これを選択でラップして取得できます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
于 2012-11-28T17:50:54.913 に答える