我需要查询来自多个表的数据,下面是主要表格(简化)。
Project
+-----+-------+-------+
| pid | pname | status| //status: 0 = pending, 1 = complete
+-----+-------+-------+
| 1 | Proj1 | 0 |
| 2 | Proj2 | 1 |
| 3 | Proj3 | 0 |
+-----+-------+-------+
Module
+-----+--------+-------+----------+-----------------+
| mid | pid | status| priority |modulecategoryid |
+-----+--------+-------+----------+-----------------+
| 1 | 1 | 1 | 1 | 1 |
| 2 | 1 | 0 | 2 | 3 |
| 3 | 3 | 1 | 1 | 1 |
| 4 | 3 | 0 | 2 | 3 |
| 5 | 3 | 0 | 3 | 5 |
+-----+--------+-------+----------+-----------------+
Task
+----+--------+-------+----------+-----------------+
| id | mid | status| priority | taskcategoryid |
+----+--------+-------+----------+-----------------+
| 1 | 2 | 1 | 2 | 2 |
| 2 | 2 | 0 | 1 | 1 |
| 3 | 4 | 1 | 1 | 2 |
| 4 | 4 | 1 | 2 | 3 |
| 5 | 4 | 0 | 3 | 4 |
| 6 | 5 | 0 | 1 | 1 |
+----+--------+-------+----------+-----------------+
我正在尝试根据模块优先级和任务优先级获取可以首先启动的所有待处理项目的待处理任务。即对于Proj3,优先级为1的模块已完成,因此我应该获得模块2的第一优先级待处理任务。
我需要使用modulecategoryid和taskcategoryid获取每个待处理项目的最先前任务,以获取此类相关信息
+-----+--------+-----+------------------+----------------+
| pid | mid | tid | modulecategoryid | taskcategoryid |
+-----+--------+-----+------------------+----------------+
| 1 | 2 | 2 | 3 | 2 |
| 2 | 4 | 5 | 3 | 4 |
+----+---------+-----+------------------+----------------+
我是MySql的新手,我尝试使用多个连接进行查询,并通过projectids和min(优先级)对其进行分组以获得所需的结果。但是,不在分组中的列是从聚合中随机获取的。
我已经看到了这个答案SQL Select only rows with Max Value on a Column,但这解决了只有一个表中数据的问题。
我能得到一些帮助吗? 如果需要,我可以发布我的查询,但是收到了错误的数据。
答案 0 :(得分:1)
SQL Select only rows with Max Value on a Column有正确的方法。你只需要做两次。
首先创建一个子查询a
,显示每个模块的最高优先级任务。
然后创建一个子查询b
,显示每个项目的最高优先级模块。
然后将三个表和两个子查询连接在一起。
此处a
。它显示每个模块id
的优先级最高的任务mid
。 (http://sqlfiddle.com/#!9/7eb1f3/4/0)
SELECT Task.id, Task.mid
FROM Task
JOIN (
SELECT MAX(priority) priority,
mid
FROM Task
WHERE status = 0
GROUP BY mid
) q ON q.priority = Task.priority AND q.mid = Task.mid
此处b
。它的工作方式与a
相同,并为每个项目mid
显示优先级最高的模块pid
。 (http://sqlfiddle.com/#!9/7eb1f3/3/0)
SELECT Module.mid, Module.pid
FROM Module
JOIN (
SELECT MAX(priority) priority,
pid
FROM Module
WHERE status = 0
GROUP BY pid
) q ON q.priority = Module.priority AND q.pid = Module.pid
然后你需要一个大的JOIN将所有东西拉到一起。在概述中它看起来像这样。
SELECT Project.pid, Project.pname,
Module.mid, Task.id tid,
Module.modulecategoryid, Task.taskcategoryid
FROM Project
JOIN ( /* the subquery called b */
) b ON Project.pid = b.pid
JOIN Module ON b.mid = Module.mid
JOIN ( /* the subquery called a */
) a ON Module.mid = a.mid
JOIN Task ON a.id = Task.id
WHERE Task.status = 0
实际查询如下所示,子查询放入。(http://sqlfiddle.com/#!9/7eb1f3/2/0)
SELECT Project.pid, Project.pname,
Module.mid, Task.id tid,
Module.modulecategoryid, Task.taskcategoryid
FROM Project
JOIN (
SELECT Module.mid, Module.pid
FROM Module
JOIN (
SELECT MAX(priority) priority, pid
FROM Module
WHERE status = 0
GROUP BY pid
) q ON q.priority = Module.priority
AND q.pid = Module.pid
) b ON Project.pid = b.pid
JOIN Module ON b.mid = Module.mid
JOIN (
SELECT Task.id, Task.mid
FROM Task
JOIN (
SELECT MAX(priority) priority, mid
FROM Task
WHERE status = 0
GROUP BY mid
) q ON q.priority = Task.priority
AND q.mid = Task.mid
) a ON Module.mid = a.mid
JOIN Task ON a.id = Task.id
WHERE Task.status = 0
这样做的秘诀是理解子查询是虚拟表,您可以将它们相互连接或连接到普通表。您需要的技能是整理所需的物理和虚拟表以及连接顺序。