高级别:
我有清单和清单都有清单项目。我想得到已经完成的清单数量。具体而言,具有核对表项目但已全部完成的核对清单。
表格
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'
此问题的问题在于它不会排除部分完成的核对表。
答案 0 :(得分: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的那些(FALSE
或NULL
)。
答案 1 :(得分: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
您可以运行子查询以查看每个检查列表中有多少不完整的项目。
答案 2 :(得分:1)
尝试:
SELECT COUNT(*)
FROM (
SELECT 1
FROM checklist_items
GROUP BY checklist_id
HAVING bool_and(completed)
) as sq
答案 3 :(得分: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
答案 4 :(得分: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