Ankündigung

Einklappen
Keine Ankündigung bisher.

Unabhängige "Auto-Increment Spalte" für ein ON DUPLICATE KEY query?

Einklappen

Neue Werbung 2019

Einklappen
Dieses Thema ist geschlossen.
X
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Unabhängige "Auto-Increment Spalte" für ein ON DUPLICATE KEY query?

    Hey,

    habe mich gefragt ob es möglich ist ein einem einzigen Query folgende Sachen unterzubringen:

    Das Query besteht aus einem INSERT INTO verknüpft mit ON DUPLICATE KEY UPDATE (ist übrigens ne Fortführung von nem Problem das bereits hier mal gelöst wurde ).

    In der Tabelle sind ein paar Spalten mit verschiedenen Parametern zu verschiedenen User IDs (die alle mehrmals vorhanden sein können).

    Eine weitere Spalte (um die es geht) soll bei jedem INSERT INTO um eins erhöht werden.

    Hier mal ein kleiner Ausschnitt:

    Code:
    +-----------+------------+--------------+-------------+
    |  userid   |  attribut  |   wert       |  increment  |
    +-----------+------------+--------------+-------------+
    |    1      |     5      |      8       |      1      |
    |    1      |     6      |      2       |      2      |
    |    3      |     2      |      4       |      1      |
    |    5      |     5      |      6       |      1      |
    |    3      |     4      |      7       |      2      |
    |    3      |     4      |      7       |      3      |
    +-----------+------------+--------------+-------------+
    // userid und attribut sind primary keys
    // Der Increment Wert startet für jede UserID bei 1

    Für den Fall dass es ein bestimmtes Attribut für die jew. UserID bereits besteht, wird der Wert verändert, falls nicht wird das Attribut und der Wert neu eingefügt:

    Code:
    INSERT INTO `table`( userid, attribut, wert) VALUES ( '3', '5', '6' ) ON DUPLICATE KEY UPDATE wert = wert + 6;
    Nun würde ich gerne noch den increment Wert für eben diese Userid um eins erhöhen. Ich nehme das Query von oben, wenn dieses ausgeführt wird ensteht eine neue Zeile (da attribut = 5 noch nicht für userid = 3 existiert).

    Der increment Wert sollte sich folglich für diese id um 1 erhöhen, d.h. die neue Zeile lautet:

    Code:
    |    3      |     5      |      6       |      4      |
    Jetzt bin ich mir absolut nicht sicher ob es möglich ist, dies noch in das obige Query mit reinzupacken. Ein Subquery dieser Art:

    Code:
    INSERT INTO `table` ( userid, attribut, wert, increment )
    VALUES (
    '3', '5', '6', (
    
    SELECT `increment`
    FROM `table`
    WHERE userid =3
    ORDER BY `listorder` DESC
    LIMIT 1
    )) ON DUPLICATE KEY UPDATE wert = wert + 6;
    ist ja leider nicht möglich:

    Code:
    #1093 - You can't specify target table
    Hat irgendjemand ne Idee, das vll doch noch alles in ein einzelnes Query zu packen (ohne dabei ne temp. Tabelle zu erstellen o.ä. eher Ressourcen unfreundliches Zeug - sonst drösel ichs doch in mehrere Queries auf)?

    Danke im Vorraus für hilfreiche Antworten!

    Gruß!

    (kleiner Nachtrag: Leute, die absolut nicht vorhaben auf das Problem einzugehen, sondern nur irgendwelche unnötigen Kommentare ablassen wollen - klickt unten auf vorheriges Thema und nervt bitte nicht mich...)

  • #2
    Schau Dir mal den MySQL REPLACE an. Das geht in eine ähnliche Richtung.

    Code:
    13.2.6. REPLACE
    
    REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [(col_name,...)]
    VALUES ({expr | DEFAULT},...),(...),...
    Oder:
    REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    Oder:
    REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [(col_name,...)]
    SELECT ..
    
    REPLACE funktioniert auf exakt gleiche Weise wie INSERT. Der Unterschied besteht darin, dass, wenn ein alter Datensatz
    denselben Wert wie ein neuer Datensatz für einen Primärschlüssel oder einen eindeutigen Index hat, der alte Datensatz gelöscht
    wird, bevor der neue eingefügt wird. Siehe auch Abschnitt 13.2.4,
    Grüße
    Thomas

    Kommentar


    • #3
      Hey Thomas,

      vielen Dank für deine Antwort. Bin zuvor schonmal über REPLACE im Manual gestolpert, allerdings bin ich mir unsicher wie ich das auf mein Beispiel anwenden kann.

      Im Prinzip ist REPLACE doch in meinem Fall nichts anderes wie ein INSERT INTO mit ON DUPLICATE KEY UPDATE, außer das bei REPLACE die Datensätze gelöscht, bei INSERT INTO die Datensätze upgedated werden, sofern sie denn schon existieren.

      Falls ich den Text zum Thema Standardwerte richtig deute, sollten auch einzelne Spalten nicht incrementiert werden, sondern es wird auf deren default Werte zurückgegriffen.

      Gruß

      Kommentar


      • #4
        Zitat von juice122 Beitrag anzeigen
        Im Prinzip ist REPLACE doch in meinem Fall nichts anderes wie ein INSERT INTO mit ON DUPLICATE KEY UPDATE, außer das bei REPLACE die Datensätze gelöscht, bei INSERT INTO die Datensätze upgedated werden, sofern sie denn schon existieren.
        Da hast Du recht. Ich habe Deine Problemstellung nicht exakt durchgelesen.

        Also ich sehe mit MySQL keine Möglichkeit dies direkt in einen SQL zu packen. Es fällt mir vorerst nur folgende triviale, aber saubere Lösungen ein:

        Einen normalen SELECT machen, wenn da nichts gefunden wird, dann INSERT.
        Wenn der SELECT was findet, dann UPDATE.


        Grüße
        Thomas

        Kommentar


        • #5
          Genau so werd ichs dann machen, danke nochmals.

          Gruß

          Kommentar


          • #6
            Worum geht es hier? Können Sie es mir sagen? Ich werde Ihnen sehr dankbar sein. Ich habe es nicht verstanden.

            Kommentar


            • #7
              Zitat von Gast Beitrag anzeigen
              Hey,

              habe mich gefragt ob es möglich ist ein einem einzigen Query folgende Sachen unterzubringen:
              ich würde auf diese increment-Spalte schlicht verzichten und diese via row_number() und partition by userid order by attribut bei der Ausgabe berechnen. Dein Beispiel ist übrigens inhaltlich fals, die Kombination von (userid,attribut), die als PK dienen soll, hat Dubletten. Bug in MySQL oder vor dem Bildschirm?
              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

              Kommentar


              • #8
                Zitat von akretschmer Beitrag anzeigen

                ich würde auf diese increment-Spalte schlicht verzichten und diese via row_number() und partition by userid order by attribut bei der Ausgabe berechnen. Dein Beispiel ist übrigens inhaltlich fals, die Kombination von (userid,attribut), die als PK dienen soll, hat Dubletten. Bug in MySQL oder vor dem Bildschirm?
                Im übrigen ginge es so, wie Du willst, mit einem einzelnen Query. Dazu müßte MySQL aber wCTE (writeable Common Table Expressions) beherrschen, was aber nicht der Fall ist.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Zitat von akretschmer Beitrag anzeigen
                  Dein Beispiel […]
                  Das Beispiel ist nicht von Samuello und der eigentliche Autor ist wohl inzwischen gelöscht worden. Der Thread ist bereits 11(!) Jahre alt und bei demjenigen der den Thread wieder ausgegraben hat würde ich mal auf einen Spambot tippen.

                  Kommentar


                  • #10
                    oh shit, ist mir nicht aufgefallen.
                    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                    Kommentar


                    • #11
                      MOD: Thema geschlossen

                      Kommentar

                      Lädt...
                      X