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

string_agg in Abfrage

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von rjentsch, 1 Februar 2021.

  1. rjentsch

    rjentsch Benutzer

    Ich habe eine frage ... war ja klar

    Ich habe eine Tabelle in der Datenbank die u.a. folgende Spalten hat
    nummer jahr sprachen tools
    1 1981 Assembler Edor
    1 1981 Cobo l Edor
    1 1981 Assembler EDT
    1 1981 Cobol EDT
    1 1981 Cobol etc.
    2 1982 Basic Edor
    2 1982 Coobl Edor

    nun möchte ich eine Abfrage erstellen die das folgende Ergebnis liefern soll

    Jahr Sprachen tools
    1981 Assember, Cobol Edor,Edt,etc.
    1982 Basic, Cobol Edor

    narürlich gibts noch viel mehr in der Tabelle nur weiss ich nicht wie ich hier die String_agg Function einsetzen soll damit es zum gewünschten Ergebnis führt

    Geht das überhaupt ?
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Nein, das geht nicht, zumindest nicht mit Deinen Daten. "Edt" aus dem Result gibt es nicht in den Ursprungsdaten, auch nicht "etc". Liefere bitte NACHVOLLZIEHBARE Beispiele, alles andere ist für die Tonne.
     
  3. rjentsch

    rjentsch Benutzer

    vielen Dankfür die konstruktive Kritik
    hier ein Auszug aus der Tabelle

    Nummer;Jahr;MM;Sprache; Tools
    1;1981;9;Assembler;EDOR
    1;1981;9;Cobol;EDOR
    1;1981;9;Assembler;EDT
    1;1981;9;Cobol;EDT
    1;1981;9;Assembler;etc.
    1;1981;9;Cobol;etc.
    2;1981;3;Basic;EDOR
    2;1981;3;Pascal;EDOR
    2;1981;3;Basic;FMS


    und so soll das Ergebnis aussehen

    Jahr MM Sprachen tools
    1981 9 Assembler, Cobol EDOR, EDT,etc.
    1982 3 Basic, Pascal, EDOR, FMS

    also die im Jahr geleisteten MM mit allen verwendeten Sprachen und allen verwendeten Tools
     
  4. rjentsch

    rjentsch Benutzer

    niemand ?
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Nein, weil aus Deine gezeigten Daten das gezeigte Resultat nicht ermittelbar ist. Da ist z.B. kein Jahr 1982 in den Ausgangsdaten. Am nächsten kommt vielleicht noch dies:

    Code:
    edb=*> select * from rjentsch;
     nummer | jahr | mm |  sprache  | tools
    --------+------+----+-----------+-------
          1 | 1981 |  9 | Assembler | EDOR
          1 | 1981 |  9 | Cobol     | EDOR
          1 | 1981 |  9 | Assembler | EDT
          1 | 1981 |  9 | Cobol     | EDT
          1 | 1981 |  9 | Assembler | etc.
          1 | 1981 |  9 | Cobol     | etc.
          2 | 1981 |  3 | Basic     | EDOR
          2 | 1981 |  3 | Pascal    | EDOR
          2 | 1981 |  3 | Basic     | FMS
    (9 rows)
    
    edb=*> select jahr, mm, string_agg(distinct sprache,',') || ',' || string_agg(distinct tools,',') from rjentsch group by jahr, mm order by jahr, mm;
     jahr | mm |           ?column?           
    ------+----+-------------------------------
     1981 |  3 | Basic,Pascal,EDOR,FMS
     1981 |  9 | Assembler,Cobol,EDOR,EDT,etc.
    (2 rows)
    
    edb=*>
    
     
  6. rjentsch

    rjentsch Benutzer

    guter Gedanke aber die String_agg function kann mit dem Parameter Disitinct nichts angangen

    und ohne Disitinct liefert sie den Fehler 9829 ... STING_AGG-Aggregation hat das Limit von 8000 Byte überschritten selbst wenn ich nur ein string_agg auf jahr mache und das sind bei 53 Datensätzen auch nicht 8000 oder mehr
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Nun ja, dann ist string_agg() in Deiner Datenbank halt schlecht oder fehlerhaft implementiert. Dafür kann ich nichts.
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Hab mal versucht, das nachzuvollziehen:

    Code:
    edb=*> insert into rjentsch select 1,1981, 9, random()::text, random()::text from generate_series(1,3) x;
    INSERT 0 3
    edb=*> select * from rjentsch ;
     nummer | jahr | mm |      sprache       |        tools       
    --------+------+----+--------------------+---------------------
          1 | 1981 |  9 | Assembler          | EDOR
          1 | 1981 |  9 | Cobol              | EDOR
          1 | 1981 |  9 | Assembler          | EDT
          1 | 1981 |  9 | Cobol              | EDT
          1 | 1981 |  9 | Assembler          | etc.
          1 | 1981 |  9 | Cobol              | etc.
          2 | 1981 |  3 | Basic              | EDOR
          2 | 1981 |  3 | Pascal             | EDOR
          2 | 1981 |  3 | Basic              | FMS
          1 | 1981 |  9 | 0.2752096951881988 | 0.19729052460242258
          1 | 1981 |  9 | 0.5846099533269999 | 0.06215803569806866
          1 | 1981 |  9 | 0.7962572541891326 | 0.5932248566620331
    (12 rows)
    
    
    Nun füge ich weitere 30.000 Rows hinzu:

    Code:
    edb=*> insert into rjentsch select 1,1981, 9, random()::text, random()::text from generate_series(1,30000) x;
    INSERT 0 30000
    edb=*> select jahr, mm, string_agg(distinct sprache,',') || ',' || string_agg(distinct tools,',') from rjentsch group by jahr, mm order by jahr, mm;
    
    Abfrage funktioniert, Ergebniss zeige ich hier aber lieber nicht ...
     
  9. rjentsch

    rjentsch Benutzer

    BTW ...würde ich eine Mysql Datenbank benutzern ( group_concat anastatt string_agg ) würde Dein Vorschlag funktionieren weil mysql auch den group_conat(distinct Feldname,":") beherrscht

    ... allerdings ist mir was || ',' || in der Abfrage erreichen soll ist mir nicht eingängig
     
  10. akretschmer

    akretschmer Datenbank-Guru

    string - concatenation:

    Code:
    edb=*> select 'Postgre' || 'SQL' as demo;
        demo   
    ------------
     PostgreSQL
    (1 row)
    
     
  11. rjentsch

    rjentsch Benutzer

    Installiert ist MS sqlserver 2019 .. und das du nichts für fehlerhaft Produkte kannst ist mir klar ... also werde ich wohl ein Programm in z.B vb oder php oder c# schreiben müssen mitdem ich dann ittereativ erreiche was ich erreichen will... oder gibts einen workaround?

    btw ... ich hasse es wenn etwas nicht wie beschrieben funktioniert und der Fehler (scheinbar) nicht bei mir liegt
     
  12. akretschmer

    akretschmer Datenbank-Guru

    besser, eine Lösung: PostgreSQL.
     
  13. castorp

    castorp Datenbank-Guru

    Der workaround ist normalerweise das DISTINCT in einem Sub-Query zu machen:

    Code:
    select string_agg(sprache, ',')
    from (
      select distinct sprache
      from ...
    ) t
     
  14. rjentsch

    rjentsch Benutzer

    Nichtmal in mysql funktioniert das so ganz, da so alle Sätze im select Disitinct nerücksichtigt werden und nicht nur jeweils gewählte und die dannauch ncoh in jedem satz
     
  15. rjentsch

    rjentsch Benutzer

    wenn du möchtest kann ich dir gerne mal einen mysqldump der gesamten DB schicken bzw. der Tabelle senden
     
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