mysql - 如何计算mysql中嵌套表架构的百分比
问题描述
我当前的表架构如下:
- 卡片表(父表
Card
:) - 每张卡片都有一个或多个列表(第二个孩子
lists
) - 每个列表有许多任务(第三个孩子
tasks
) - 每当用户填写一项任务时,它将被填写在一个名为 (
user_tasks
)的单独表格中
因此,如果您想想象它就像树卡 => 很多卡列表 => 很多列表任务。
卡片
身份证 | 姓名
列表
身份证 | 卡号 | 姓名
任务
身份证 | Lists_Id | Card_Id | 标题
用户任务
身份证 | 任务ID | 用户 ID | 内容
现在我需要编写一个查询或一个简单的逻辑,我根本无法计算出每张卡片的进度。
卡片进度是根据用户完全填写的列表来计算的。
例子:
- 卡片 1 有 3 个列表,每个列表有 4 个任务
用户填写了这些列表中的所有任务 (4x3),卡片进度将为 3/3。
- 卡片 1 有 3 个列表,每个列表有 4 个任务
用户填写了任意 2 个列表 (4x2) 中的所有任务,卡片进度将为 2/3
- 卡片 1 有 3 个列表,每个列表有 4 个任务
用户在列表 1 中仅填写了 2 个任务,其中包含 4 个任务,卡片进度将为 0/3
因此,要考虑完成的列表,用户必须完成所有任务。有人可以指导我如何执行嵌套表架构的逻辑以使卡片取得进展吗?
所以我希望输出以任何方式如下:
{
card_id: 1,
total_lists: 10
total_filled: 3
}
继续,在数据库中的所有卡片上......
解决方案
您可以使用以下查询
SELECT target.cardid as 'card_id', target.total as 'total_lists', IFNULL(progress.total,0) as 'total_filled'
FROM (SELECT l.cardid, Count(l.id) total
FROM lists l
GROUP BY l.cardid) target
LEFT JOIN (SELECT l.cardid, userlist.userid, Count(userlist.listid) total
FROM lists l
INNER JOIN (SELECT ut.userid, t1.listid, Count(ut.taskid) tcount
FROM user_tasks ut
INNER JOIN tasks t1 ON t1.id = ut.taskid
GROUP BY ut.userid, t1.listid) userlist --- STEP#1
ON l.id = userlist.listid
INNER JOIN (SELECT t.listid, Count(*) tcount
FROM tasks t
GROUP BY t.listid) tasklist --- STEP#2
ON userlist.listid = tasklist.listid AND userlist.tcount = tasklist.tcount --- STEP#3
GROUP BY l.cardid, userlist.userid) progress -- STEP#4
ON target.cardid = progress.cardid;
描述:
Step#1
:确定每个 user_id 和 list_id 的任务数Step#2
: 确定所有列表的每个 list_id 的任务数Step#3
:过滤user_task
列表中没有所有任务条目的记录Step#4
user_task
:获取包含所有任务条目的列表计数- 最后,加入
target
和progress
子查询以获取最终结果。
演示: https ://www.db-fiddle.com/f/5tAzoL49SSd2SJDK5k19a3/3
注意:几个观察
- 理想情况下, table
tasks
不应该有cardid
,只有listid
必须存在。 - 2个不同的用户可以在同一张卡上工作吗?在这种情况下,在结果中,您还需要包含
userid
。参考 - https://www.db-fiddle.com/f/5tAzoL49SSd2SJDK5k19a3/4
推荐阅读
- excel - 使用多行和多列调整 Excel 表格的大小 - VBA
- python - Django DRF:如何显示过滤后的数据
- javascript - 捕获 iframe 上的点击事件
- database - 将多个数据库合并到一个数据库中,没有任何重复条目
- python - 这个 Python 类型提示语法是什么,括号中的两种类型?
- typescript - 在打字稿中使用带有接口的默认值
- java - 如何授予对 JAR 文件的基于角色的访问权限
- laravel - Laravel 什么时候应该扩展或包含或编写双重代码?
- bash - 用于检查哪个端口正在侦听并运行命令的 Bash 脚本
- google-colaboratory - 如何将文件从 kaggle 移动到 google drive usig google colab