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

(T)-SQL While/If Schleife mit mehreren Bedingungen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Lukas2016, 15 Juli 2016.

  1. Lukas2016

    Lukas2016 Benutzer

    Hallo zusammen,

    ich hoffe jemand kann mir beim folgenden MS SQL Problem weiterhelfen.

    Ich versuche die Spalte (B) basierend auf den Werten in Spalte (A) zu berechnen. Mit einer anschließenden Generierung einer Eindeutigen ID in Spalte (C). Die Spalte RowID ist sortiert.

    upload_2016-7-15_11-23-21.png

    Die Bedingung für Spalte B lautet:

    Solange der Wert in Spalte A < 30 ist, dann soll in Spalte B fleißig weiter hochgezählt werden und eine eindeutige ID in Spalte C generiert werden.
    Bei nicht Erfüllung der Bedingung soll eine 0 gestzt werde und wieder von neu gezählt werden.

    Kann mir hier jemand behilflich sein?

    Das wäre Klasse! Vielen Dank im Vorraus!
    Gruß
     

    Anhänge:

  2. Lukas2016

    Lukas2016 Benutzer

    Eine Berechnung wäre in diesem Zusammenhang glaube ich falsch. Es geht eher um ein Rank() in Spalte B.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    jepp. Irgend was mit row_number() oder so. Ich hab nur grad keine Idee für die Nestart des zählens.
     
  4. ukulele

    ukulele Datenbank-Guru

    Da du nicht grade mit MySQL arbeitest würde ich von einer Schleife absehen, Schleifen sind was für Noobs. Allerdings wirft deine Frage weitere Fragen auf:
    a) RowID ist die Reihenfolge, aber ist es auch lückenlos?
    b) Ist der Eintrag mit der ersten Zahl größer gleich 30 schon der erste Eintrag der nächsten Gruppe oder gehört er zu den Datensätzen davor? Die ID in C sagt, er gehört zu denen davor. B sagt, er fängt wieder an zu zählen, beginnt also eine neue Gruppe.
    c) Wiso beginnt B einmal mit 1 und dann immer mit 0, ist das so gewollt?
    d) Welches Format hat deine "eindeutige ID"?

    Hier mal ein Testaufbau. Ich arbeite mit GUID als eindeutiger ID und fange eine neue GUID an wenn B = 0 ist. Wenn es wie in dem Beispiel sein soll muss man eventuell zwei Update-Befehle machen. Aber vielleicht ist heute auch nur einfach zu sehr Freitag, daher mach dir mal erst Gedanken über meine Fragen.
    Code:
    CREATE TABLE test(
       RowID INT,
       A INT,
       B INT,
       C UNIQUEIDENTIFIER
       );
    
    INSERT INTO test(RowID,A) VALUES (1,2),(2,5),(3,2),(4,30),(5,9),(6,5),(7,7),(8,256),(9,15),(10,5);
    Code:
    WITH t(RowID,A,B,C) AS (
       SELECT   t1.RowID,
           t1.A,
           ( CASE WHEN t2.RowID IS NULL THEN 1 ELSE 0 END ) AS B,
           newid() AS C
       FROM   test t1
       LEFT JOIN test t2
       ON     t2.RowID = t1.RowID - 1
       WHERE   t2.RowID IS NULL
       OR     t1.A >= 30
       UNION ALL
       SELECT   test.RowID,
           test.A,
           t.B + 1 AS B,
           t.C
       FROM   t
       INNER JOIN test
       ON     t.RowID + 1 = test.RowID
       AND     test.A < 30
       )
    UPDATE   test
    SET     test.B = t.B,
         test.C = t.C
    FROM   test
    INNER JOIN t
    ON     test.RowID = t.RowID
    
    SELECT   *
    FROM   test
     
    Lukas2016 gefällt das.
  5. Lukas2016

    Lukas2016 Benutzer

    Hallo Ukulele,

    vielen Dank fürs Feedback!

    Hier sind meine Antworten auf deine Fragen:

    Zu a) Ja, die Reihenfolge ist lückenlos
    Zu b) Also der Eintrag sollte noch zur Gruppe davor gehören.
    Zu c) Ja, hier ist der Wurm drin. Die neue Zählung sollte immer mit dem Wert 1 beginnen.

    upload_2016-7-19_0-3-1.png

    Vielen Dank & Gruß,
     
  6. ukulele

    ukulele Datenbank-Guru

    Habe es etwas umgestellt und es funktioniert soweit. Genutzt wird aber eine GUID als eindeutige ID.
    Code:
    CREATE TABLE test(
       RowID INT,
       A INT,
       B INT,
       C UNIQUEIDENTIFIER
       );
    
    INSERT INTO test(RowID,A) VALUES (1,2),(2,5),(3,2),(4,30),(5,9),(6,5),(7,7),(8,256),(9,15),(10,5);
    Code:
    WITH t(RowID,A,B,C) AS (
       SELECT   t1.RowID,
           t1.A,
           1 AS B,
           newid() AS C
       FROM   test t1
       LEFT JOIN test t2
       ON     t1.RowID = t2.RowID + 1
       WHERE   t2.RowID IS NULL
       OR     t2.A >= 30
       UNION ALL
       SELECT   test.RowID,
           test.A,
           t.B + 1 AS B,
           t.C
       FROM   t
       INNER JOIN test
       ON     t.RowID + 1 = test.RowID
       AND     t.A < 30
       )
    UPDATE   test
    SET     test.B = t.B,
         test.C = t.C
    FROM   test
    INNER JOIN t
    ON     test.RowID = t.RowID
    
    SELECT   *
    FROM   test
    ORDER BY RowID
     
    Zuletzt bearbeitet: 20 Juli 2016
    Lukas2016 gefällt das.
  7. Lukas2016

    Lukas2016 Benutzer

    Hallo Ukulele,

    vielen Dank, das ist perfekt!

    Gruß
     
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