2013-04-24 83 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