4

高水平:

我有清单,清单有清单项目。我想获得已完成的清单的计数。具体来说,包含清单项目但已全部完成的清单。

表:

Table "checklists"

|     Column   |          Type          |
+--------------+------------------------+
| id           | integer                |
| name         | character varying(255) |

Table "checklist_items"

|     Column   |          Type          |
+--------------+------------------------+
| id           | integer                |
| completed    | boolean                |
| name         | character varying(255) |
| checklist_id | integer                |

问题: 什么查询会给我完成的清单计数?具体来说,要小心排除清单项目既完整又不完整的清单以及没有清单项目的清单。

到目前为止尝试过:

SELECT DISTINCT COUNT(DISTINCT "checklists"."id")
  FROM "checklists"
INNER JOIN "checklist_items" ON "checklist_items"."checklist_id" = "checklists"."id"
  WHERE "checklist_items"."completed" = 't'

这个问题的问题在于它不排除部分完成的清单。

4

5 回答 5

4

更快,但:

SELECT count(DISTINCT i.checklist_id)
FROM   checklist_items i
LEFT   JOIN checklist_items i1 ON i1.checklist_id = i2.checklist_id
                              AND i.completed IS NOT TRUE
WHERE i.completed
AND   i1.checklist_id IS NULL;

这仅收集存在已完成项目的清单。
并排除那些存在另一个未完成的 checklist_item (FALSENULL)。

于 2013-04-26T19:02:35.297 回答
2

以下使用子查询执行此操作:

select COUNT(*)
from (select cl.id,
             SUM(case when cli.completed <> 't' or cli.completed is null then 1 else 0 end) as NumIncomplete
      from checklists cl join
           checklist_items cli
           ON cli.checklist_id = cl.id
      group by cl.id
     ) t
where NumIncomplete = 0

您可以运行子查询以查看每个检查列表有多少不完整的项目。

于 2013-04-26T17:47:08.167 回答
1

尝试:

SELECT COUNT(*)
FROM   (
         SELECT 1
         FROM checklist_items
         GROUP BY checklist_id
         HAVING bool_and(completed)
       ) as sq
于 2013-04-26T17:51:06.763 回答
0

假设空清单被认为已完成(尽管您也可以修改它以删除空清单)。

SELECT checklists.id 
FROM checklists LEFT JOIN (SELECT DISTINCT checklist_id 
                           FROM checklist_items WHERE completed = 'f') partial_checklists 
                ON checklists.id = partial_checklists.checklist_id 
WHERE partial_checklists.checklist_id = NULL

排除空清单(尽管我不确定这里的语法):

SELECT checklists.id 
FROM checklists LEFT JOIN (SELECT checklist_id 
                           FROM checklist_items WHERE completed = 'f' 
                         UNION DISTINCT 
                           SELECT checklist_id 
                           FROM checklist_items 
                           GROUP BY checklist_id 
                           HAVING count(*) = 0) partial_checklists 
                  ON checklists.id = partial_checklists.checklist_id 
WHERE partial_checklists.checklist_id = NULL
于 2013-04-26T17:47:57.517 回答
0
select count(*) completed_items
from (
    select
        c.id, c.name, count(*) total_items
    from
        checklists c
        inner join
        checklist_items ci on c.id = ci.checklist_id
    group by c.id, c.name
    having count(!completed or null) = 0
) s
于 2013-04-26T17:48:42.767 回答