【问题标题】:How to improve/simplify query with subqueries?如何使用子查询改进/简化查询?
【发布时间】:2013-04-24 08:43:40
【问题描述】:

我想知道一个人的最大阵型,一个人可以有很多阵型条目。

表格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

【问题讨论】:

  • 为什么不包括1 and 3
  • 你能解释一下你的问题吗??
  • 我用 2 个子查询进行了查询。然后先显示查询。还要解释你的预期结果。请不要在提出问题后离开。
  • 没有3个fkPerson
  • 请发布查询或至少发布所需的输出

标签: mysql view subquery


【解决方案1】:

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

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

您可以使用子查询获取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

附带说明,您的示例数据似乎无法提供您要求的结果。 fkPerson = 2 的最大 orderLevel 是 3 而不是 2,因此编队将是 University 而不是 High School

【讨论】:

  • 是的,你是对的,最后一行或 t_formatoin 必须是这样的 5 | 2 | 3 |我的高
  • 哪一个查询更快或更轻?我想这将是第一个
  • 我会接受第一个建议。可能首先执行子选择并将其他表连接到它,以便在执行连接时更轻松地利用索引。第二种解决方案使用相关子查询,这些子查询的性能可能很差。
  • @Joe 我会使用第一个版本的查询。
【解决方案2】:

为什么不使用

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

?

【讨论】:

  • 我没有得到预期的结果,这个查询是你的 SELECT fkPerson, orderLevel as maxOrderLevel , formation, place FROM t_formation as a LEFT external JOIN a_level as b ON a.fkLevel = b.idLevel GROUP通过 fkPerson HAVING orderLevel = max(orderLevel) 我只得到一条记录而不是两条:s
猜你喜欢
  • 1970-01-01
  • 2011-10-27
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-16
相关资源
最近更新 更多