2016-12-22 29 views
1

我需要从多个表中查询数据,下面是主要表(简化)。从两个表中获取最小(优先级)的行

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(priority)对它进行分组以获得所需的结果。但不在组中的列从聚合中随机提取。

我已经看到这个答案SQL Select only rows with Max Value on a Column但是这只能解决一个表中数据的问题。

我可以得到一些帮助吗? 如果需要,我可以发布我的查询,但它得到错误的数据。

+0

如果您仍在挣扎,请参阅http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-tobe -a-very-simple-sql-query – Strawberry

回答

1

SQL Select only rows with Max Value on a Column有正确的做法。你只需要做两次。

首先创建子查询a,显示每个模块的最高优先级任务。

然后创建一个子查询b,显示每个项目的最高优先级模块。

然后将您的三个表格和两个子查询结合在一起。

这是a。它显示每个模块mid的最高优先级任务id。 (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相同,并为每个项目pid显示最高优先级模块mid。 (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 

的秘密,这是了解该子查询有虚表可以彼此连接或普通表格。您需要的技能是整理您需要的物理和虚拟表以及连接顺序的组合。

+0

哦,我很抱歉。我错过了你的问题。您需要使用'MIN(优先级)',我使用了'MAX(优先级)' –

+0

Hi @O。琼斯,我非常感谢你们的帮助!加入模块和任务的结果时我遇到了问题,但这看起来不错。这是简化的模式,所以我会试一试并回来。 –

+0

我有7个表加入的结果,所以我会稍后尝试,但我可以看到在sqlfiddle这是工作正如我所料。解释这么好的答案。非常感谢! +1已接受。 –