如何使用子查询改进/简化查询?

时间:2013-04-24 08:43:40

标签: mysql view subquery

我想知道人的最高形成水平,一个人可以有很多阵型。

t_formation

idFormation | fkPerson   | fkLevel     | place
------------------------------------------------
    1       |     1      |     2       | Oxford
    2       |     2      |     1       | PlaySchool
    3       |     1      |     3       | Trinity High
    4       |     1      |     1       | My School
    5       |     2      |     3       | My High

a_level

idLevel | orderLevel | formation
-------------------------------------
  1     |   1        |  School
  2     |   3        |  University
  3     |   2        |  High school

我需要获得以下查询或所需的查询结果 (最大订单水平与每个人的形成以及他们研究最大形成的地方

fkPerson | maxOrderLevel |  formation    |  place
----------------------------------------------------
      1  |      2        |   Univertity  |  Oxford
      2  |      3        |   High school |  My High

为此,我用2个子查询进行了查询,但无法创建有效的视图。

在没有地点的情况下查询SQL ,这可以最大限度地形成每个人

select fkPerson, a_level.orderLevel, a_level.formation
from (
  select fkPerson,  max(a_level.orderlevel) as ordermax
  from t_formation left join a_level on t_formation.fkLevel = a_level.idLevel 
  group by fkPerson
) as form left join a_level on form.ordermax = a_level.orderlevel

2 个答案:

答案 0 :(得分:2)

问题的一部分是,每个orderLevel可以有多个fkPerson值,因此您必须为每个max(orderLevel)检索fkPerson,然后执行另一个联接获取与每个人相关联的place / formation

我看到了几种可以获得结果的方法。

您可以使用子查询获取max(orderLevel),然后加入表格以返回所需的列:

select t1.fkPerson, 
  at.MaxOrder,
  t1.Place,
  a.Formation
from t_formation t1
inner join a_level a
  on t1.fkLevel = a.idLevel
inner join
(
  select t.fkPerson, max(a.orderLevel) MaxOrder
  from t_formation t
  left join a_level a
    on t.fkLevel  = a.idLevel
  group by t.fkPerson
) at
  on t1.fkPerson = at.fkPerson
  and at.maxorder = a.orderLevel;

请参阅SQL Fiddle with Demo

您可以获得结果的另一种方法是使用WHERE子句中的查询来过滤没有max(orderLevel)的行:

select t.fkperson,
  a.orderlevel,
  t.place,
  a.formation
from t_formation t
left join a_level a
  on t.fkLevel = a.idLevel
where a.orderlevel = (select max(orderlevel)
                      from a_level a
                      inner join t_formation t1
                        on a.idlevel = t1.fklevel
                      where t.fkperson = t1.fkperson
                      group by t1.fkperson);

请参阅SQL Fiddle with Demo

作为旁注,您的样本数据似乎无法提供您请求的结果。 orderLevel的最大fkPerson = 2为3而不是2,因此格式为University而不是High School

答案 1 :(得分:0)

为什么不使用

SELECT fkPerson, fkLevel,orderLevel, formation, place
FROM t_formation as a 
LEFT OUTER JOIN a_level as b ON a.fkLevel = b.idLevel
GROUP BY fkPerson HAVING orderLevel = max(orderLevel)
;