ScaraX: mysql INSERT ... SELECT problem

Hi,

ich habe folgendes Problem:
Ich habe eine Tabelle links (id (AutoIncrement), title, url, position)

Beim Einfügen eines neuen Links soll die Position auf (max(position) + 1) gesetzt werden.

Ich könnte das ganze so regeln, dass ich zuerst in einem eigenen query max(position) zu ermitteln und das dann in einem zweiten query mit einem einfachen INSERT einzufügen.

Allerdings gibt es ja auch die INSERT ... SELECT syntax in mysql, und daher wollte ich versuchen das in einem einzelnen Query zu lösen.

Mein Bisheriger Ansatz fügt allerdings NULL für die Position ein:

INSERT INTO links
    (title, url, position)
SELECT
 'Meine Seite',
 'http://example.com/foo',
 ((MAX(position)) + 1)
FROM links;

Kann mir jemand sagen was ich hier falsch mache?

Danke schonmal für eure Antworten :)

MfG
ScaraX

  1. Hi,

    Ich habe eine Tabelle links (id (AutoIncrement), title, url, position)

    Beim Einfügen eines neuen Links soll die Position auf (max(position) + 1) gesetzt werden.

    Welchen Zweck erfüllt diese Spalte neben der auto_increment-ID, die doch automatisch hochgezählt wird?

    Ich könnte das ganze so regeln, dass ich zuerst in einem eigenen query max(position) zu ermitteln und das dann in einem zweiten query mit einem einfachen INSERT einzufügen.

    Nein, dann fängst du dir ein Nebenläufigkeitsproblem ein.

    Mein Bisheriger Ansatz fügt allerdings NULL für die Position ein:

    INSERT INTO links
        (title, url, position)
    SELECT
    'Meine Seite',
    'http://example.com/foo',
    ((MAX(position)) + 1)
    FROM links;

    Hast du dir mal angeschaut, was dir das SELECT-Statement liefert, wenn du es einzeln ausführst?

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    1. P.S.:

      Ich habe eine Tabelle links (id (AutoIncrement), title, url, position)

      Beim Einfügen eines neuen Links soll die Position auf (max(position) + 1) gesetzt werden.

      Welchen Spaltentyp hat position?

      MfG ChrisB

      --
      “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    2. Welchen Zweck erfüllt diese Spalte neben der auto_increment-ID, die doch automatisch hochgezählt wird?

      In diesem beispiel keinen, allerdings wollte ich die Tabelle noch um Kategorien erweitern, wodurch auto increment dann nicht mehr funktioniert.

      Nein, dann fängst du dir ein Nebenläufigkeitsproblem ein.

      Ein Grund mehr für diesen Ansatz ;)

      Welchen Spaltentyp hat position?

      position ist INT(11) NOT NULL

      Hast du dir mal angeschaut, was dir das SELECT-Statement liefert, wenn du es einzeln ausführst?

      MfG ChrisB

      habe jetzt herausgefunden, dass der query wunderbar funktioniert, sobald mindestens ein Eintrag vorhanden ist.
      Wenn kein Eintrag vorhanden ist, liefert max(position) allerdings NULL (auch wenn NOT NULL für position festgelegt ist)
      und NULL + 1 bleibt NULL

      Die Frage ist jetzt wie ich daraus 1 machen kann...

      MfG
      ScaraX

      1. Hi,

        Wenn kein Eintrag vorhanden ist, liefert max(position) allerdings NULL (auch wenn NOT NULL für position festgelegt ist)
        und NULL + 1 bleibt NULL

        Die Frage ist jetzt wie ich daraus 1 machen kann...

        IFNULL()

        MfG ChrisB

        --
        “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
        1. IFNULL()

          MfG ChrisB

          Danke, funktioniert wunderbar!

          Mein Query ist jetzt:
          INSERT INTO links
              (title, url, position)
          SELECT
           'Meine Seite',
           'http://example.com/foo',
           (IFNULL(MAX(position),0) + 1)
          FROM links;

          MfG
          ScaraX

        2. Hi!

          Die Frage ist jetzt wie ich [aus NULL] 1 machen kann...
          IFNULL()

          Und COALESCE(position, 0).

          Lo!

  2. INSERT INTO links
        (title, url, position)
    SELECT
    'Meine Seite',
    'http://example.com/foo',
    ((MAX(position)) + 1)
    FROM links;

    Du kannst unter MySQL nicht gleichzeitig eine Tabelle verändern *und* abfragen, dein Statement sollte also eine Fehlermeldung produzieren.

    In deinem Fall könntest du dich über Trigger informieren.

    1. Hi,

      Du kannst unter MySQL nicht gleichzeitig eine Tabelle verändern *und* abfragen, dein Statement sollte also eine Fehlermeldung produzieren.

      Nicht in halbwegs aktuellen Versionen - siehe http://dev.mysql.com/doc/refman/5.0/en/insert-select.html:

      The target table of the INSERT statement may appear in the FROM clause of the SELECT part of the query. (This was not possible in some older versions of MySQL.)

      MfG ChrisB

      --
      “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]