Unterschiedliche Spalten summieren

DerAmatuer

Benutzer
Beiträge
7
Hallo zusammen,

ich habe die folgende Beispieltabelle (Auszug):

Text 1 | Text 2 | Wert 1 | Wert 2
A | B | 1 | 3
A | C | 3 | 2
C | A | 1 | 4
B | C | 5 | 2
A | B | 2 | 4
B | A | 3 | 4

Ich benötige nun eine Auswertung welche die Summe für A etc. bildet. Dabei hat immer Text 1 zu Wert 1 und Text2 zu Wert2 einen Bezug, also kommt A in Text1 vor dann summieren mit Wert1, kommt A in Text2 vor dann summieren mit Wert 2.

Als Ergebnis sollte also bei dem Beispiel rauskommen:
A | 14
B | 15
C | 5

Bis jetzt mach ich das mit zwei einzelnen Abfragen und summiere dann die beiden Ergebnisse miteinander (also SUM(Wert1) und SUM(Wert2) und dann Addieren).

Bekomme ich das auch mit EINER Abfrage direkt hin? Meine Ansätze mit OR bringen leider nicht den gewünschten Erfolg.

Danke im Voraus.
 
Werbung:
Code:
test=*# select * from der_amateur ;
 t1 | t2 | w1 | w2
----+----+----+----
 A  | B  |  1 |  3
 C  | A  |  1 |  4
 B  | C  |  5 |  2
 A  | B  |  2 |  4
 B  | A  |  3 |  4
 A  | C  |  3 |  2
(6 rows)

test=*# with foo as (select t1,w1 from der_amateur union all select t2,w2 from der_amateur ) select t1, sum(w1) from foo group by t1 order by t1;
 t1 | sum
----+-----
 A  |  14
 B  |  15
 C  |   5
(3 rows)

test=*#

Da ist nur eine andere Reihenfolge bei mir in der Ausgangstabelle, aber das ist ja egal. Du hast aber meiner Meinung nach ein kapottes Tabellendesign.
 
Rein technisch gesehen macht akretschmer auch zwei Abfragen und summiert dann das Ergebnis, ist aber der eleganteste Weg. Dir gehts vermutlich nicht um die Anzahl der Tabellenabfragen sondern du willst es in einem Select haben, das wäre hier der Fall.

Alternativ kannst du ein ekeliges CASE-Konstrukt bauen, dann wird die Tabelle tatsächlich nur einmal gelesen.
 
Vielen Dank für die schnelle Antworten!
Ja das Tabellendesign befriedigt mich auch nicht, aber ich komm auf keine bessere Lösung.
Letztendlich handelt es sich um Spielergebnisse, also z.B. A gegen B, C gegen A etc. Und dann muss ich herausfinden wie viel Punkte A insgesamt erzielt hat.
Ich hatte es auch schon so dass ich eben sage: Spiel 1 - A- 1 Punkt, Spiel 2- A- 4 Punkte ...... Dann wird halt die Datenbank doppelt so groß und brauch eine Spalte um den Zusammenhang zwischen den Teams herzustellen.
 
Alternativ kannst du ein ekeliges CASE-Konstrukt bauen, dann wird die Tabelle tatsächlich nur einmal gelesen.

Daran dachte ich auch schon, nur: wenn der Inhalt der ersten beiden Spalten variable ist (also später auch noch L oder O oder Z dazukommen können, dann müßte man das Select wieder anpassen. Oder das Select gleich dynamisch basteln und dann EXECUTE. Vermutlich wäre ein besseres Tabellendesign der einfachste Weg ...
 
Mit Standard SQL könnte man das recht leicht so lösen:
Code:
select x.text, sum(x.wert)
from data
  cross join lateral (values (text1, wert1), (text2, wert2) ) as x(text,wert)
group by x.text;
Aber wenn ich das richtig im Kopf habe, dann unterstützt MySQL weder lateral joins noch VALUES in der Art.

Ein sauberes Tabellendesign läuft auf ein klassisches many-to-many Design hinaus:
  • Eine Tabelle für die Spieler
  • Eine Tabelle für die Spiele ("A gegen B")
  • Und eine Spiele die für jeden Spieler die Anzahl der Punkte in einem Spiel speichert
Sowas in der Art:
Code:
create table player
(
  id integer primary key,
  name varchar(100)
);

create table match
(
  id integer not null primary key,
  player_one integer not null,
  player_two integer not null,
  match_date date,
  ... weitere Attribute
  foreign key (player_one) references player (id),
  foreign key (player_two) references player (id)
);

create table player_points
(
  player_id integer not null,
  match_id integer not null,
  points integer not null,
  foreign key (player_id) references player(id),
  foreign key (match_id) references match(id),
  primary key (player_id, match_id)
);

Und dann wird die Abfrage ganz einfach:
Code:
select p.name, sum(pt.points)
from player p
  join player_points pt on pt.player_id = p.id
group by p.name
order by p.name;

Online Beispiel: spiele, PostgreSQL - rextester
 
Werbung:
Zurück
Oben