1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Unterschiedliche Spalten summieren

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von DerAmatuer, 28 Mai 2019.

  1. DerAmatuer

    DerAmatuer Benutzer

    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.
     
  2. akretschmer

    akretschmer Datenbank-Guru

    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.
     
  3. ukulele

    ukulele Datenbank-Guru

    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.
     
  4. DerAmatuer

    DerAmatuer Benutzer

    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.
     
  5. akretschmer

    akretschmer Datenbank-Guru

    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 ...
     
  6. DerAmatuer

    DerAmatuer Benutzer

    Ok, dann geh ich mal das Tabellendesign an.

    Danke euch!
     
  7. castorp

    castorp Datenbank-Guru

    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
     
    Walter und DerAmatuer gefällt das.
  8. DerAmatuer

    DerAmatuer Benutzer

    Oh, ein sehr guter Ansatz, vielen Dank!
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden