方法函数不从单行获取值(嵌套表)

时间:2017-10-12 10:41:08

标签: sql oracle plsql

您好我问了一个问题related to this already,但有第二个问题。我评论说,我创建了一个嵌套的团队表,其中包括每个团队的得分而不是单独的行。

我想为特定的GameId而不是表格中的所有行运行Method ..这次我已经包含了我的Game_Type对象,虽然我上次认为没必要。

CREATE TYPE Game_Type AS OBJECT
(GameId NUMBER)
/
CREATE TABLE Game_Table of Game_Type
/
INSERT INTO Game_Table 
VALUES (1)
/
INSERT INTO Game_Table
VALUES (2)
/
CREATE TYPE Team_Type AS OBJECT
(TeamPlayed VARCHAR2(30),
TeamScore NUMBER(1))
/

CREATE TYPE TeamsPlayed_Table as TABLE OF Team_Type
/
CREATE OR REPLACE TYPE After_Team AS OBJECT
(GameRef REF Game_Type,
GamePlayed Teamsplayed_Table,
MAP MEMBER FUNCTION team_rating RETURN NUMBER)
/
CREATE TABLE Team_Table of After_Team NESTED TABLE GamePlayed STORE AS 
GamePlayed_Nested
/
CREATE OR REPLACE TYPE BODY After_Team
AS
MAP MEMBER FUNCTION team_rating
  RETURN NUMBER
IS 
avg_score NUMBER;
BEGIN
SELECT AVG(c.TeamScore)
INTO avg_score
FROM Team_Table d, table(d.GamePlayed) c;
RETURN avg_score;
END;
END;
/

INSERT INTO Team_Table 
VALUES((SELECT REF(a) FROM Game_Table a WHERE a.gameid = 1), 
(TeamsPlayed_Table(Team_Type('Team A', 1), Team_Type('Team B', 3))))
/

INSERT INTO Team_Table 
VALUES((SELECT REF(a) FROM Game_Table a WHERE a.gameid = 2), 
(TeamsPlayed_Table(Team_Type('Team C', 5), Team_Type('Team D', 9))))
/

现在当我执行我的方法时:

SELECT t.team_rating()
from Team_Table t
where t.GameRef.GameId = 1

它返回所有值的平均值,而不仅仅是游戏1 ..

1 个答案:

答案 0 :(得分:1)

假设您想获得该团队的TeamScore集合中GamePlayed的平均值,那么您可以在纯PL / SQL中执行此操作(无需将上下文切换到SQL范围中):

CREATE OR REPLACE TYPE BODY After_Team
AS
  MAP MEMBER FUNCTION team_rating
    RETURN NUMBER
  IS 
    avg_score NUMBER := 0;
    j INTEGER := 0;
  BEGIN
    FOR i IN 1 .. self.GamePlayed.COUNT LOOP
      IF self.GamePlayed(i) IS NOT NULL AND self.GamePlayed(i).TeamScore IS NOT NULL THEN
        avg_score := avg_score + self.GamePlayed(i).TeamScore;
        j := j + 1;
      END IF;
    END LOOP;
    IF j > 0 THEN
      RETURN avg_score / j;
    ELSE
      RETURN NULL;
    END IF;
  END;
END;
/

SQLFIDDLE

否则,您可以使用:

CREATE OR REPLACE TYPE BODY After_Team
AS
  MAP MEMBER FUNCTION team_rating
    RETURN NUMBER
  IS 
    avg_score NUMBER;
  BEGIN
    SELECT avg( TeamScore )
    INTO   avg_score
    FROM   TABLE( self.GamePlayed );

    RETURN avg_score;
  END;
END;
/

SQLFIDDLE