akone: Datensätze zusammenfügen

Hallo,

meine DB sieht ungefähr so aus:

ID | name | f1 | f2 | f3 | datum
---|------|----|----|----|-------
1  | hans | 1  |    | 3  | 2007
2  | hans | 2  | 14 |    | 2008

Ich möchte jetzt das Datensätze mit gleichem "name" zusammengefügt werden.
Also auf obiges Beispiel bezogen sollte das Ergebnis so aussehen.

ID | name | f1 | f2 | f3 | datum
---|------|----|----|----|-------
x  | hans | 2  | 14 | 3  | 2008

Die ID (hier "x") ist vollkommen egal, meinetwegen kann auch ein neuer Datensatz angelegt werden.
Die "2" in "f1" soll die 1 überschreiben, da Datensatz 2 aktueller ist(siehe PseudoDatum).

Mein Problem dabei ist, das meine Tabelle nicht wirklich so einfach aussieht, sondern ca. 1500 Spalten hat.

Im Augenblick versuche ich das über 3 Anfragen zu regeln. Zuerst lese ich alle Spaltenköpfe (s1) aus, danach suche ich doppelte Daten und lass mir den aktuelleren Ausgeben (d1). Dann bastele ich in PHP einen MySQL-Update-Query aus s1 und d1, in dem nur die in d1 gefüllten Felder übertragen werden.

Geht das eventuell etwas kürzer bzw. performanter?

  1. Mein Problem dabei ist, das meine Tabelle nicht wirklich so einfach aussieht, sondern ca. 1500 Spalten hat.

    1500 spalten (aka felder) ist dein ernst?

    1. Ja die 1500 sind nötig.
      Bis jetzt ist die Performance ganz gut, ich benötige aber auch nur einfache Ein- und Ausgabefunktionalitäten. Das Zusammenfügen ist die komplizierteste Funktion die die Tabelle je ausführen wird.

      1. Hallo,

        Ja die 1500 sind nötig.
        Bis jetzt ist die Performance ganz gut,

        Hinweis: Limits in MySQL.

        Noch eine Anmerkung: Eine id ist kein besonders gutes oder brauchbares Mittel, um zu entscheiden, ob ein Datensatz neuer oder älter ist als ein anderer. Eine id sollte einzig und allein dazu da sein, einen Datensatz zu _id_entifizieren.

        Freundliche Grüße

        Vinzenz

        1. Die ID entscheidet das auch nicht. Die Spalte Datum entscheidet, ob ein Eintrag aktueller ist oder nicht.

  2. Hallo

    meine DB sieht ungefähr so aus:

    ID name f1 f2 f3 datum
    1 hans 1 3 2007
    2 hans 2 14 2008

    Ich möchte jetzt das Datensätze mit gleichem "name" zusammengefügt werden.
    Also auf obiges Beispiel bezogen sollte das Ergebnis so aussehen.

    ID name f1 f2 f3 datum
    x hans 2 14 3 2008

    Die ID (hier "x") ist vollkommen egal, meinetwegen kann auch ein neuer Datensatz angelegt werden.
    Die "2" in "f1" soll die 1 überschreiben, da Datensatz 2 aktueller ist(siehe PseudoDatum).

    Geht das eventuell etwas kürzer bzw. performanter?

    Klassischer Fall für eine korrelierte Unterabfrage.

    Freundliche Grüße

    Vinzenz

    1. Soweit ich korrelierte Unterabfragen verstanden hab, passt das leider nicht wirklich.

      Ich will und kann nicht 1500 Spaltennamen für die Updatefunktion eingeben und auswerten.
      Bei wenig Spalten würde die korrelierte Unterabfrage schon funktionieren, aber ich glaube in meinem Beispiel wird leider nichts.

      Wobei ich mich natürlich auch gern vom Gegenteil überzeugen lasse. :)

      1. Hallo

        Soweit ich korrelierte Unterabfragen verstanden hab, passt das leider nicht wirklich.

        dann hast Du sie nicht verstanden.

        Ich will und kann nicht 1500 Spaltennamen für die Updatefunktion eingeben und auswerten.

        Ach nein. Warum hast Du dann 1500 Spalten angelegt?

        Bei wenig Spalten würde die korrelierte Unterabfrage schon funktionieren, aber ich glaube in meinem Beispiel wird leider nichts.

        Wo ist das Problem. Eine korrelierte Unterabfrage hat doch nichts mit der Spaltenzahl zu tun.

        Wobei ich mich natürlich auch gern vom Gegenteil überzeugen lasse. :)

        Selbstverständlich verwende ich in meinen Beispielen Spaltenlisten. Ich halte SELECT * im normalen Anwendungsfall für überflüssig, in den meisten Fällen sogar für schädlich. Ich versuche das zu zeigen, was ich für guten Stil halte.

        Freundliche Grüße

        Vinzenz

        1. Könntest du mir den mysql-Code für meine obiges Beispiel bitte posten?
          Ich habe das Gefühl wir reden aneinander vorbei.

          Ich kann mir jedenfalls keinen query erdenken, in dem überprüfe ob ein Feld belegt ist oder nicht um danach dieses bei belegung in einen anderen Eintrag zu kopieren, OHNE dabei den Spaltennamen absolut einzutippen.

  3. yo,

    Mein Problem dabei ist, das meine Tabelle nicht wirklich so einfach aussieht, sondern ca. 1500 Spalten hat.

    mal davon abgesehen, dass wir den grund für 1500 spalten nicht kennen (sehr aussergewöhnlich), wäre wohl die beste methode, die tabellen aus dem data dictionary des dbms mit einzubeziehen und darüber eine abfrage zu basteln.

    ich kenne sie in mysql leider nicht (bin Oracler), aber dort habe ich die möglichkeit, mir jede spalte der tabelle anzeigen zu lassen, egal wieviele das sind. das könnte man ausnutzen, um eine geeignete abfrage für dich zu entwickeln, ohne dass du alle 1500 spaltennamen selbst benennen musst.

    Ilja