PostgreSQL中的函数从一个表插入另一个表?

时间:2015-01-25 00:27:19

标签: postgresql insert

我有以下内容:

我得到了表格:

Equipos(团队)

Teams Table

Partidos(比赛) Matches Table

列num_eqpo_loc&表partidos中的num_eqpo_vis引用了表equipo。它们引用num_eqpo列。 正如你在这里看到的那样:

create table equipos
(num_eqpo serial,     
ciudad varchar (30),
num_gpo int, 
nom_equipo varchar (30), 
primary key (num_eqpo), 
foreign key (num_gpo) references grupos (num_gpo))

create table partidos 
(semana int, 
num_eqpo_loc int, 
num_eqpo_vis int, 
goles_loc int, 
goles_vis int, primary key (semana,num_eqpo_loc,num_eqpo_vis), 
foreign key (num_eqpo_loc) references equipos (num_eqpo), 
foreign key (num_eqpo_vis) references equipos (num_eqpo))

我想获得以下输出:

Output Table 1

一方面,我创建了一个名为general的表:

Tabla General

CREATE TABLE general
(
  equipo character varying(30) NOT NULL,
  partidos_jug integer,
  partidos_gana integer,
  partidos_emp integer,
  partidos_perd integer,
  puntos integer,
  goles_favor integer,
  CONSTRAINT general_pkey PRIMARY KEY (equipo)
)

另一方面,我有这个功能:

CREATE OR REPLACE FUNCTION sp_tablageneral ()  RETURNS TABLE (
    equipo character varying(30)
  , partidos_jug int
  , partidos_gana int
  , partidos_emp int
  , partidos_perd int
  , puntos int
  , goles_favor int) AS
$BODY$
DECLARE cont int:= (SELECT count(num_eqpo)FROM equipos);
r partidos%ROWTYPE;
BEGIN

    while cont>0
    LOOP

    SELECT INTO equipo nom_equipo FROM equipos AS E WHERE E.num_eqpo=cont;
    SELECT INTO partidos_jug COUNT(*) FROM partidos as P WHERE (P.num_eqpo_loc=cont OR P.num_eqpo_vis=cont);
    SELECT INTO partidos_gana COUNT(*) FROM partidos AS P WHERE (P.num_eqpo_loc=cont AND P.goles_loc>P.goles_vis OR P.num_eqpo_vis=cont AND P.goles_vis>P.goles_loc);
    SELECT INTO partidos_emp COUNT(*) FROM partidos AS P WHERE (P.num_eqpo_loc=cont AND P.goles_loc=P.goles_vis OR P.num_eqpo_vis=cont AND P.goles_loc=P.goles_vis);
    SELECT INTO partidos_perd COUNT(*) FROM partidos as P WHERE ( (P.num_eqpo_loc=cont AND P.goles_loc<P.goles_vis) OR (P.num_eqpo_vis=cont AND P.goles_loc>P.goles_vis));
    SELECT INTO puntos partidos_emp*1 + partidos_gana*3;
    SELECT INTO goles_favor SUM(goles_loc) FROM partidos as P WHERE P.num_eqpo_loc=cont + (SELECT SUM(goles_vis) FROM partidos as P WHERE P.num_eqpo_vis=cont);

    cont:= cont - 1;
    END LOOP;

  RETURN NEXT ; 
 END;
$BODY$ LANGUAGE plpgsql STABLE;

我希望该功能显示我想要的输出&amp;我还希望表'General'从所需的输出中获得相同的值。

通过这个功能,我得到:

Tabla

我不知道如何查看所需内容,因为我只获取第一行数据。 我也想知道如何从函数返回的表中插入名为General的现有表。

编辑:我也尝试过:

CREATE OR REPLACE FUNCTION sp_tablageneral ()  RETURNS TABLE (
    equipo character varying(30)
  , partidos_jug int
  , partidos_gana int
  , partidos_emp int
  , partidos_perd int
  , puntos int
  , goles_favor int) AS
$BODY$
DECLARE cont int:= (SELECT count(num_eqpo)FROM equipos);
r partidos%ROWTYPE;
BEGIN

    while cont>0
    LOOP

        SELECT INTO equipo nom_equipo FROM equipos AS E WHERE E.num_eqpo=cont;
    SELECT INTO partidos_jug COUNT(*) FROM partidos as P WHERE (P.num_eqpo_loc=cont OR P.num_eqpo_vis=cont);
    SELECT INTO partidos_gana COUNT(*) FROM partidos AS P WHERE (P.num_eqpo_loc=cont AND P.goles_loc>P.goles_vis OR P.num_eqpo_vis=cont AND P.goles_vis>P.goles_loc);
    SELECT INTO partidos_emp COUNT(*) FROM partidos AS P WHERE (P.num_eqpo_loc=cont AND P.goles_loc=P.goles_vis OR P.num_eqpo_vis=cont AND P.goles_loc=P.goles_vis);
    SELECT INTO partidos_perd COUNT(*) FROM partidos as P WHERE ( (P.num_eqpo_loc=cont AND P.goles_loc<P.goles_vis) OR (P.num_eqpo_vis=cont AND P.goles_loc>P.goles_vis));
    SELECT INTO puntos partidos_emp*1 + partidos_gana*3;
    SELECT INTO goles_favor SUM(goles_loc) FROM partidos as P WHERE P.num_eqpo_loc=cont + (SELECT SUM(goles_vis) FROM partidos as P WHERE P.num_eqpo_vis=cont);

    SELECT equipo, partidos_jug , partidos_gana, partidos_emp , partidos_perd , puntos , goles_favor INTO equipo,partidos_jug,partidos_gana,partidos_emp,partidos_perd,puntos,goles_favor FROM general;

    cont:= cont - 1;
        END LOOP;

  RETURN NEXT ; 
 END;
$BODY$ LANGUAGE plpgsql STABLE;

但我明白了:

ERROR: the reference to the column "equipo" is ambiguous 
LINE 1: SELECT equipo , partidos_jug, partidos_gana, partidos_emp ...
                ^
********** Error **********
ERROR: the reference to the column "equipo" is ambiguous 
SQL state: 42702
Detail: It could refer either to a variable PL / pgSQL as a column in a table.
Context: PL / pgSQL sp_tablageneral () function on line 17 in SQL statement

任何帮助都会很棒。

提前致谢!

1 个答案:

答案 0 :(得分:0)

您可以在纯SQL中解决此问题,您不需要此功能。

最好的办法是将统计数据集合分成两个不同的查询,一个用于团队在家中比赛时,一个用于比赛时。每场比赛计算得分和得分。然后UNION这两个查询并将其用作子查询来计算总体统计信息:

SELECT
  eq.nom_equipo AS equipo,
  COUNT(p.*) AS partidos_jug,
  SUM(CASE WHEN p.puntos = 3 THEN 1 ELSE 0 END) partidos_gana,
  SUM(CASE WHEN p.puntos = 1 THEN 1 ELSE 0 END) partidos_emp,
  SUM(CASE WHEN p.puntos = 0 THEN 1 ELSE 0 END) partidos_perd,
  SUM(p.puntos) AS puntos,
  SUM(p.goles) AS goles_favor
FROM equipos eq
JOIN (
  -- Playing at home
  SELECT
    num_eqpo_loc AS eqpo, 
    CASE WHEN (goles_loc > goles_vis) THEN 3
         WHEN (goles_loc = goles_vis) THEN 1
         ELSE 0
    END AS puntos,
    goles_loc AS goles
  FROM partidos
  UNION
  -- Playing away
  SELECT
    num_eqpo_vis AS eqpo, 
    CASE WHEN (goles_vis > goles_loc) THEN 3
         WHEN (goles_vis = goles_loc) THEN 1
         ELSE 0
    END AS puntos,
    goles_vis AS goles
  FROM partidos) AS p ON p.eqpo = eq.num_eqpo
GROUP BY equipo
ORDER BY puntos DESC, partidos_jug ASC, goles_favor DESC;

由于CASE语句,这不是特别快,但它比使用过程和循环更快。

我建议您CREATE VIEW general AS ...使用上述查询,而不是将此查询的结果放入表中。在这种情况下,您在SELECT * FROM general时始终获得最新结果,并且在运行查询之前不必使用TRUNCATE通用表(在表中添加包含数据的新结果将违反PK约束) 。如果您确实需要该表,请在上面的查询中使用SELECT ... INTO general FROM ...