2013-02-04 47 views
2

对于下表(我用**来表示主键的部分),我需要 SQL查询,力图提高效率(Oracle DBMS中)

Team (*tid*, name) 
Game (*gid*, tid, name, year) 
Member (*mid*, name) 
MemberOf (*mid*, *tid*, startyear, endyear, position) 

显示各史前锋(位置) 如果startyear为null,则使用从该玩家的那支球队 结果最早年度游戏:前锋名称,队名,开始年份,结束年份 由前锋名称排序,然后开始一年

虽然我有一个解决方案,我不认为它非常有效 执行计划推断节点成本为28. 是否希望获得改进建议和解释?

+0

你试过联盟吗?这些对我来说看起来是互斥的查询,UNION ALL不会尝试过滤出重复的内容。当然,确保UNION ALL返回完全相同的结果。 – HLGEM

+0

我没有看到任何能够让我找到特定团队最早比赛的年份的领域。你的游戏桌是否有一个你不显示的日期字段? –

+0

谢谢HLGEM,全部都保存在节点上的费用 丹,你的权利,我错过了!编辑添加 – Hector

回答

2

你可以用一个查询做到这一点,利用left outer join和​​3210(如果我有逻辑正确):

SELECT Striker_Name, Team_Name, coalesce(MO.STARTYEAR, g.start_year), MO.ENDYEAR 
FROM (SELECT NAME AS Striker_Name, MID 
     FROM MEMBER 
    ) ME JOIN 
     (SELECT MID, TID, STARTYEAR AS Start_Year, ENDYEAR AS End_Year 
     FROM MEMBEROF 
     WHERE POSITION = 'striker' 
    ) MO ON ME.MID = MO.MID left outer JOIN 
     (SELECT NAME AS Team_Name, TID 
     FROM TEAM 
    ) T 
     ON MO.TID = T.TID left outer JOIN 
     (SELECT GID, MIN(GAME.YEAR) AS Start_Year FROM GAME GROUP BY TID 
    ) G 
     ON G.TID = MO.TID 
ORDER BY Striker_Name, Start_Year 

你似乎在今年开始从最早的游戏填充。只需加入并在select中决定使用哪一个。

+0

谢谢,它似乎接近我后,但是这似乎只返回的结果,其中STARTYEAR为NULL? – Hector

+0

@ user2036256。 。 。我想我错过了其中一个联结。他们应该全部留下外部联接。 –

+0

唯一的其他连接是第一个连接。将其更改为左侧外部只会导致所有成员被列出! – Hector