简体   繁体   English

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

[英]How to improve/simplify query with subqueries?

I want to know the maximum formation level of people, and a person can have many formation entries. 我想知道一个人的最大编队水平,一个人可以有很多编队条目。

Table t_formation 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

Table a_level a_level

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

What I need to get is the following query or desired query result ( the max order level with formation of each person and the place where they studied that max formation ) 我需要得到的是以下查询或所需的查询结果( 每个人的构成的最大订单级别以及他们研究该最大构成的位置

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

To do that, I made a query with 2 subquerys but it was impossible to create a efficient view. 为此,我使用2个子查询进行了查询,但是无法创建有效的视图。

Query SQL without place, this get max formation of each person 查询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

Part of the problem is that you can have multiple orderLevel values for each fkPerson so you will have to retrieve the max(orderLevel) for each fkPerson and then perform another join to get the place / formation that is associated with each person. 问题的部分原因是,你可以有多个orderLevel每个值fkPerson所以你将不得不检索max(orderLevel)每个fkPerson然后执行另一加入以获得place / formation与每个人相关。

I see a couple ways that you can get the result. 我看到了几种获得结果的方法。

You can use a subquery to get the max(orderLevel) and then join on your tables to return the desired columns: 您可以使用子查询获取max(orderLevel) ,然后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;

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle

The other way that you could get the result would be to use a query in your WHERE clause to filter the rows that do not have the max(orderLevel) : 获得结果的另一种方法是在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);

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle

As a side note, your sample data does not seem to be able to give the result that you request. 附带说明一下,您的示例数据似乎无法提供您要求的结果。 The max orderLevel for fkPerson = 2 is 3 not 2 so the formation will be University not High School . fkPerson = 2的最大orderLevel是3而不是2,因此组将是University而不是High School

Why not use 为什么不使用

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)
;

?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM