Je rencontre un problème où j'essaie d'ajouter deux sommes SELECT de la même table mais avec des conditions différentes en un seul résultat.

Voici le code:

DROP TABLE Match CASCADE CONSTRAINTS;

CREATE TABLE Match 
(
    Heim VARCHAR(50),
    Gast VARCHAR(50),
    HeimP NUMBER,
    GastP NUMBER
);

INSERT INTO Match 
VALUES ('Bayern München', 'Borussia Dortmund', 1, 1);

INSERT INTO Match 
VALUES ('Borussia Dortmund', 'Bayern München', 0, 3);
INSERT INTO Match 
VALUES ('Bayern München', 'Schalke', 3, 0);
INSERT INTO Match 
VALUES ('Schalke', 'Bayern München', 0, 3);

COMMIT;


SELECT SUM(HeimP) AS Heimpoints 
FROM Match 
WHERE Heim = 'Bayern München';

SELECT SUM(GastP) AS Gastpoints 
FROM Match 
WHERE Gast = 'Bayern München';
2
Christopher Wilger 29 août 2020 à 17:56

3 réponses

Meilleure réponse

Vous pouvez utiliser une expression CASE dans SUM():

SELECT SUM(
         CASE 'Bayern München'
           WHEN Heim THEN HeimP 
           WHEN Gast THEN GastP
         END
       ) AS points 
FROM Match 
WHERE 'Bayern München' IN (Gast, Heim);

Voir la démo.
Résultats:

> | POINTS |
> | -----: |
> |     10 |
1
forpas 29 août 2020 à 15:08

Le NUMBER me fait penser que vous utilisez Oracle. Il s'agit d'une base de données qui prend en charge les jointures latérales (qui sont SQL standard mais non prises en charge par toutes les bases de données).

Quelque chose comme ça pourrait être la solution la plus simple:

select sum(x.points)
from match m cross join lateral
     (select m.heimp as team, m.heimp as points from dual union all
      select m.gast, m.gastp from dual
     ) x
where x.team = 'Bayern München';

Cela présente l'avantage par rapport aux autres solutions de ne faire référence qu'une seule fois à l'équipe spécifique (évitant ainsi les fautes de frappe). Peut-être plus important encore, il se généralise facilement à toutes les équipes:

select x.team sum(x.points)
from match m cross join lateral
     (select m.heimp as team, m.heimp as points from dual union all
      select m.gast, m.gastp from dual
     ) x
group by x.team;

Dans les bases de données qui ne prennent pas en charge les jointures latérales, vous pouvez faire quelque chose d'assez similaire en utilisant union all.

1
Gordon Linoff 29 août 2020 à 15:18

Une façon de procéder consiste à remplacer les conditions de la clause where par des conditions dans une expression case et à ne additionner que les lignes pertinentes:

SELECT SUM(CASE heim WHEN 'Bayern München' THEN heimp END) AS Heimpoints,
       SUM(CASE gast WHEN 'Bayern München' THEN gastp END) AS Gastpoints
FROM   match
WHERE  'Bayern München' IN (heim, gast) -- optimization to not query useless rows
1
Mureinik 29 août 2020 à 15:00