none
Update einer Spalte mit mehreren Datensätzen aus einer verknüpften Tabelle

    Frage

  • Hallo,

    habe eine Tabelle, die die Werte zum Updaten liefert:

    ID sk_ident_work Lst_ident zaehler_begruendung gop_begruendung 

    8 6540853_74 26 1 nach 10x Akupunktur Schmerzreduktion von initial VAS 6 auf 3 

    9 6540853_74 26 2 . zur weiteren Schmerzreduktion Verlängerung + 5 Akupunkturs 

    10 6540853_74 26 3 itzungen 

    Diese ist mit der Ergebnistabelle über sk_ident_work und Lst_ident verknüpft. In der Ergebnistabelle ist dazu jeweils nur ein Datensatz vorhanden, in der Werte liefernden Tabelle können dazu auch mehrere Datensätze vorliegen, diese identifizieren sich über zaehler_begruendung, hier 1, 2, 3. ID ist übrigens der Primärschlüssel.

    Ich möchte nun die aufnehmende Tabelle so updaten, dass in der Ergebnisspalte die einzelnen Einträge verkettet und zwar in der Reihenfolge  zaehler_begruendung von 1 nach 2 nach 3 vorliegen. Nur dann macht der Text Sinn, also:

    nach 10x Akupunktur Schmerzreduktion von initial VAS 6 auf 3            1
    . zur weiteren Schmerzreduktion Verlängerung + 5 Akupunkturs          2
    itzungen                                                                                          3

    Tatsächlich erhalte ich im Ergebnis was anderes, mit

    DoCmd.RunSQL "
    UPDATE GOP_Table INNER JOIN GOP_Begr
    ON (GOP_Table.Lst_ident = GOP_Begr.Lst_ident) AND
    (GOP_Table.sk_ident_work = GOP_Begr.sk_ident_work)
    SET GOP_Table.gop_begruendung =[GOP_Table].[gop_begruendung] & [GOP_Begr].[gop_begruendung]  ;
    "

    erhalte ich:

    . zur weiteren Schmerzreduktion Verlängerung + 5 Akupunkturs         2
    itzungen                                                                                         3
    nach 10x Akupunktur Schmerzreduktion von initial VAS 6 auf 3           1

    die Abfrage direkt in Access ausgeführt:

    nach 10x Akupunktur Schmerzreduktion von initial VAS 6 auf 3           1
    itzungen                                                                                         3
    . zur weiteren Schmerzreduktion Verlängerung + 5 Akupunkturs         2

    Was ist die Ursache, gibt es eine Lösung mit SQL?

    Gruß Tom

    Donnerstag, 1. Juni 2017 11:08

Antworten

  • Hallo Tom,

    ich befürchte das wird im Acess nicht ganz so einfach, da bei einem UPDATE keine ORDER BY erlaubt ist.

    Ich habe jetzt zwar eine Lösung gefunden, die wird Dir aber nicht gefallen.

    Zunächst musste Du eine temporäre tabelle anlegen, die den gleichen Aufbau hat wie Dein GOP_Begr. Diese Tabelle befüllst Du mit dem Inhalt von GOP_Begr und zwar in umgekehrter reihenfolge von zaehler ORDER BY DESC (das ist wichtig).

    Wenn Du nun Dein UPDATE mit dieser temporären Tabelle ausführst wird das Ergebnis in der richtigen Reihenfolge zusammen gesetzt.

    Als Alternative kann ich nur VBA-Code nennen.

    Viele Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 07:12
    Donnerstag, 1. Juni 2017 14:31
  • Falls Dir das besser gefällt hier die Variante über VBA Code:

    Public Sub Combine()
    
    Dim rs1 As Recordset
    Dim rs2 As Recordset
    Dim SK As String
    Dim strCombined As String
    
    Set rs2 = CurrentDb.OpenRecordset("TabelleErgebnis")
    Do Until rs2.EOF
      strCombined = ""
      SK = rs2.Fields("Sk")
      Set rs1 = CurrentDb.OpenRecordset("Select * FROM TabelleTexte WHERE SK='" & SK & "' Order By zaehler")
      Do Until rs1.EOF
        strCombined = strCombined + rs1.Fields("Text")
        rs1.MoveNext
      Loop
      rs2.Edit
      rs2.Fields("text").Value = strCombined
      rs2.Update
      rs2.MoveNext
    Loop
    
    End Sub

    Den Code musst Du noch etwas an Deine Bedürfnisse anpassen.

    Bei mir heissen die Tabellen

    TabelleTexte und

    TabelleErgebnis

    Als Datentypen für sk habe ich Text verwendet, das musst Du gegebenfalls noch beachten wenn Du den  Select Teil im Recordset zusammenbaust.

    Grüße

    Roland



    • Bearbeitet Roland Franz Donnerstag, 1. Juni 2017 14:59
    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 07:12
    Donnerstag, 1. Juni 2017 14:56
  • Hallo Tom,

    ich habe mich wahrscheinlich missverständlich ausgedrückt.

    Mit "temporärer Tabelle" meinte ich eine, in einem von mir separaten Schritt angelegte normale Tabelle, die wieder entfernt werden kann. Daher bin ich auch selbst von dieser Methode nicht sehr begeistert.

    Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 09:07
    Freitag, 2. Juni 2017 07:49
  • Hallo Tom,

    schön dass es bei Dir auch funktioniert.

    Zum Hintergrund kann ich leider nicht viel sagen, ich würde mich letztendlich auch nicht darauf verlassen, dass das in einer nächsten Access Version nicht anders aussieht.

    Vermutlich liegt das an der internen rekursiven Abarbeitung des Joins. Bei einer Rekursion sieht das in der Regel auch so aus. Es wird also rekursiv die Verknüpfte Tabelle mit dem Verknüpfungskriterium abgearbeitet und die Daten auf einem Stack abgelegt. Nach dem letzen Datensatz werden die  Daten wegens des Stacks in umgekehrter Reihenfolge wieder ausgelesen.

    Zumindest  brachte mich diese Überlegung auf die Idee mit der umgekehrten Sortierung.

    Viele Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 10:27
    Freitag, 2. Juni 2017 09:36

Alle Antworten

  • Hallo Tom,

    ich muss gestehen, dass ich deine Ausführungen nicht verstanden habe. Da fehlen doch einige wichtige Informationen.

    Poste bitte mal die CREATE TABLE Statements der Tabellen, INSERT INTO Statements für die Beispieldaten und dann das gewünschte Ergebnis nach dem UPDATE.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 1. Juni 2017 12:17
    Moderator
  • Hallo, Stefan

    ich versuchs nochmal anders.


    die Tabelle, die die Werte zum Updaten liefert, auszugsweise:

    ID1  sk  Lst  zaehler  text

    8  6540853  26  1  "So "

    9  6540853 26  2  "soll"

    10  6540853 26  3  "s sein"

    ID1 ist primKey, sk kann mehrfach auftreten. Wenn ich die Tabelle in der Datenblattansicht öffne, sind die Datensätze nach ID1 aufsteigend geordnet.


    die Ergebnistabelle auszugsweise vor dem Update:

    ID2 sk Lst text

    12345 6540853 26 ""


    Ziel nach Update:

    ID2 sk Lst text

    12345 6540853 26 "So solls sein"


    Ergebnis über
    DoCmd.RunSQL "
     UPDATE GOP_Table INNER JOIN GOP_Begr
     ON (GOP_Table.Lst_ident = GOP_Begr.Lst_ident) AND
     (GOP_Table.sk_ident_work = GOP_Begr.sk_ident_work)
     SET GOP_Table.gop_begruendung =[GOP_Table].[gop_begruendung] & [GOP_Begr].[gop_begruendung]  ;
     "

    ID2 sk Lst text

    12345 6540853 26 "soll s seinSo "


    die Abfrage direkt in Access ausgeführt:

    ID2 sk Lst text

    12345 6540853 26 "So s seinsoll"


    verständlicher?

    Gruß Tom

    Donnerstag, 1. Juni 2017 13:03
  • Hallo Tom,

    Poste bitte mal die CREATE TABLE Statements der Tabellen, INSERT INTO Statements für die Beispieldaten und dann das gewünschte Ergebnis nach dem UPDATE.

    das wäre das, was hilfreich ist.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 1. Juni 2017 13:19
    Moderator
  • Hallo Tom,

    ich befürchte das wird im Acess nicht ganz so einfach, da bei einem UPDATE keine ORDER BY erlaubt ist.

    Ich habe jetzt zwar eine Lösung gefunden, die wird Dir aber nicht gefallen.

    Zunächst musste Du eine temporäre tabelle anlegen, die den gleichen Aufbau hat wie Dein GOP_Begr. Diese Tabelle befüllst Du mit dem Inhalt von GOP_Begr und zwar in umgekehrter reihenfolge von zaehler ORDER BY DESC (das ist wichtig).

    Wenn Du nun Dein UPDATE mit dieser temporären Tabelle ausführst wird das Ergebnis in der richtigen Reihenfolge zusammen gesetzt.

    Als Alternative kann ich nur VBA-Code nennen.

    Viele Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 07:12
    Donnerstag, 1. Juni 2017 14:31
  • Falls Dir das besser gefällt hier die Variante über VBA Code:

    Public Sub Combine()
    
    Dim rs1 As Recordset
    Dim rs2 As Recordset
    Dim SK As String
    Dim strCombined As String
    
    Set rs2 = CurrentDb.OpenRecordset("TabelleErgebnis")
    Do Until rs2.EOF
      strCombined = ""
      SK = rs2.Fields("Sk")
      Set rs1 = CurrentDb.OpenRecordset("Select * FROM TabelleTexte WHERE SK='" & SK & "' Order By zaehler")
      Do Until rs1.EOF
        strCombined = strCombined + rs1.Fields("Text")
        rs1.MoveNext
      Loop
      rs2.Edit
      rs2.Fields("text").Value = strCombined
      rs2.Update
      rs2.MoveNext
    Loop
    
    End Sub

    Den Code musst Du noch etwas an Deine Bedürfnisse anpassen.

    Bei mir heissen die Tabellen

    TabelleTexte und

    TabelleErgebnis

    Als Datentypen für sk habe ich Text verwendet, das musst Du gegebenfalls noch beachten wenn Du den  Select Teil im Recordset zusammenbaust.

    Grüße

    Roland



    • Bearbeitet Roland Franz Donnerstag, 1. Juni 2017 14:59
    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 07:12
    Donnerstag, 1. Juni 2017 14:56
  • Moin Stefan, ich weiss nicht, was Du meinst: Tabelle GOP_Table wird kopiert von einer leeren Schablone mit gleicher Struktur, also in dem Moment kein Create Table verwendet. Tabelle GOP_Begr entsteht durch einlesen einer Textdatei zeilenweise per ADODB. Die ID1 wird nachträglich hinzugefügt. Da die Belegung der Spalte ID1 exakt mit dem Einlesen UND mit der logischen Reihenfolge der zusammengehörenden Datensätze übereinstimmt, ging ich davon aus, dass die physische Ablage genau dem entspricht und bei einer Verknüpfung wie beschrieben der Datensatz ID1=8 vor ID1=9 und der wiederum vor ID1=10 angesteuert wird. Verstehst Du unter den Statements irgendwelche SystemInformationen zu den Tabellen? Gruß Tom
    Freitag, 2. Juni 2017 04:45
  • Moin Roland,

    nun, Deine SQL-Variante wäre eine zusätzliche Code-Zeile im Gegensatz zu einer Lösung per VBA. Die Lösung würde mir gefallen, wenn sie denn funktioniert.

    Allerdings verstehe ich nicht, weshalb Deine Lösung funktionieren sollte. Aber ich probier das gleich aus.

    (Ich werde die Umsortierung in einer Unterabfrage vornehmen)

    Was ist denn der Grund für dieses Verhalten?

    Gruß Tom


    • Bearbeitet Casi_G Freitag, 2. Juni 2017 04:54
    Freitag, 2. Juni 2017 04:51
  • Hallo Roland,

    hat damit nicht geklappt.

    UPDATE GOP_Table_mit_Begr_und_OPS INNER JOIN
    (
    select * from GOP_Begr order by ID desc
    ) as j
     ON (GOP_Table_mit_Begr_und_OPS.Lst_ident = j.Lst_ident) AND (GOP_Table_mit_Begr_und_OPS.sk_ident_work = j.sk_ident_work) SET GOP_Table_mit_Begr_und_OPS.gop_begruendung =j.[gop_begruendung] & [GOP_Table_mit_Begr_und_OPS].[gop_begruendung]  ;

    Ich habe dann die Unterabfrage in einer Abfrage gespeichert und diese dann eingebunden, ebenfalls negativ.

    Gruß Tom

    Freitag, 2. Juni 2017 05:26
  • Hallo Tom,

    das geht leider nicht mit Abfragen oder Unterabfragen. Du musst tatsächlich eine temporäre Tabelle anlegen. Das habe ich getestet und das hat auch funktioniert. Persönlich würde ich diesem Fall aber ausnahmsweise die VBA-Variante vorziehen.

    Grüße

    Roland



    Freitag, 2. Juni 2017 05:38
  • Hallo Roland,

    hab mich diesbezüglich erstmal belesen. Bisher nahm ich an, dass Abfragen temporäre Tabellen erzeugen würden ;)

    Ich habe Access 2010, das Beispiel von MSDN funktioniert nicht mehr, wenn ich das Schlüsselwort TEMPORARY reinnehme, es heißt dann Syntaxfehler in Create Table ??

    CREATE TEMPORARY TABLE ThisTable (FirstName CHAR, LastName CHAR);

    Gruß Tom

    Freitag, 2. Juni 2017 07:13
  • Hallo Tom,

    ich habe mich wahrscheinlich missverständlich ausgedrückt.

    Mit "temporärer Tabelle" meinte ich eine, in einem von mir separaten Schritt angelegte normale Tabelle, die wieder entfernt werden kann. Daher bin ich auch selbst von dieser Methode nicht sehr begeistert.

    Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 09:07
    Freitag, 2. Juni 2017 07:49
  • Hi Roland,

    hat nun auch bei mir geklappt.

    Jetzt interessiert mich brennend der Hintergrund!!!!!

    also die temp absteigend sortiert:

    ID1  sk  Lst  zaehler  text

    10  6540853 26  3  "s sein"

    9  6540853 26  2  "soll"

    8  6540853  26  1  "So "

    aber beim Update wird der Wert aus der temp hinten angehängt. klingt total verrückt!

    Gruß Tom

    Freitag, 2. Juni 2017 09:06
  • Hallo Tom,

    schön dass es bei Dir auch funktioniert.

    Zum Hintergrund kann ich leider nicht viel sagen, ich würde mich letztendlich auch nicht darauf verlassen, dass das in einer nächsten Access Version nicht anders aussieht.

    Vermutlich liegt das an der internen rekursiven Abarbeitung des Joins. Bei einer Rekursion sieht das in der Regel auch so aus. Es wird also rekursiv die Verknüpfte Tabelle mit dem Verknüpfungskriterium abgearbeitet und die Daten auf einem Stack abgelegt. Nach dem letzen Datensatz werden die  Daten wegens des Stacks in umgekehrter Reihenfolge wieder ausgelesen.

    Zumindest  brachte mich diese Überlegung auf die Idee mit der umgekehrten Sortierung.

    Viele Grüße

    Roland

    • Als Antwort markiert Casi_G Freitag, 2. Juni 2017 10:27
    Freitag, 2. Juni 2017 09:36
  • Danke Roland,

    Schöne Pfingsten

    Freitag, 2. Juni 2017 10:27