2013-04-24 80 views
-1

我想知道人的最大形成水平,并且一​​个人可以有许多编队条目。如何通过子查询改进/简化查询?

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个subquerys但它是不可能创造一个高效的视图。

查询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

为什么不包括'1和3'? – 2013-04-24 08:45:42

+0

你能解释一下你的问题吗? – 2013-04-24 08:51:47

+1

*我用2个subquerys *进行了查询。然后首先显示查询。同时解释你的预期结果。提出问题后请不要离开。 – hims056 2013-04-24 08:58:02

回答

2

的部分是你可以为每个fkPerson多个orderLevel值,所以你将不得不检索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

+0

是的,你是右,最后一行或t_formatoin必须是这样的 5 | 2 | 3 |我的高 – Joe 2013-04-28 19:17:32

+0

哪一个会更快或更不重要?我想这将是第一个 – Joe 2013-04-29 08:44:16

+2

我会与第一个建议去。可能先执行子查询并将其加入其他表中,以便在进行连接时更容易利用索引。第二种解决方案使用相关的子查询,这些可以执行得不好。 – Kickstart 2013-04-29 08:54:56

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

?问题的

+0

我不同意这种查询得到预期的结果和你 SELECT fkPerson,orderLevel为maxOrderLevel,平整,放置 FROM t_formation作为 LEFT OUTER JOIN a_level为b ON a.fkLevel = b.idLevel GROUP BY fkPerson HAVING orderLevel = MAX(orderLevel) 我得到只有一条记录,而不是两个:■ – Joe 2013-04-27 18:03:32