none
Anzahl von Datensätzen in Gruppen aufteilen RRS feed

  • Frage

  • Hallo

    ich möchte eine Anzahl von x Datensätzen einer Tabelle nach dem Zufall in x Gruppen aufteilen (z.B. 50 Datensätze in 5 Gruppen), damit ich die einzelnen Gruppen dann später selectieren kann. 

    Über ein Update sollen dann jeweils die Zahlen 1-5 in ein integer Feld der Datensätze eingetragen werden.

    Hat jemand einen Tipp für mich?


    Liebe Grüße, die Luzie!

    Mittwoch, 9. Dezember 2020 08:32

Antworten

  • Hallo Luzie,

    probiers mal so:

    DECLARE @Teilnehmer TABLE( ID int NOT NULL, Vorname nvarchar( 50 ), Nachname nvarchar( 50 ), Gruppe int );
    
    INSERT INTO @Teilnehmer ( ID, Vorname, Nachname )
    VALUES ( 1, 'Max', 'Mustermann' ),
           ( 2, 'Felix', 'Schmidt' ),
           ( 3, 'Wolfgang', 'Müller' ),
           ( 4, 'Erika', 'Mustermann' ),
           ( 5, 'Luzie', 'Schulte' ),
           ( 6, 'Anton', 'Rößler' ),
           ( 7, 'Siegfried', 'Marx' ),
           ( 8, 'Wanda', 'Fisch' );
    
    WITH Query AS
    (
    SELECT ID,
           Vorname,
           Nachname,
           ROW_NUMBER() OVER( ORDER BY NEWID() ) AS RowNumber
    FROM   @Teilnehmer
    )
    SELECT ID,
           Vorname,
           Nachname,
           ( RowNumber % 5 ) AS Gruppe
    FROM   Query

    Beim nächsten mal bitte die Tabellendefinition und das INSERT Statement bitte selbst erzeugen. Dann können wir uns dem eigentlichen Problem schneller zuwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    • Als Antwort markiert Luzie Samstag, 12. Dezember 2020 08:49
    Mittwoch, 9. Dezember 2020 10:02
    Moderator

Alle Antworten

  • Hallo Luzie,

    bitte poste das Tabellen Design als DDL, ein paar Beispiel Daten als DML SQL Skript und das erwartet Ergebnis; so ist die Beschreibung zu abstrakt.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Mittwoch, 9. Dezember 2020 09:06
  • Hallo Olaf, 

    danke für die Rückmeldung. 

    Ich habe eine Selection einer Adressdatenbank (Vorname,Nachname,Firma etc) mit Verknüpfung zu einer Seminartabelle. Zu diesem Seminar haben sich jetzt bspw. 50 Teilnehmer angemeldet. Die Seminare finden derzeit coronabedingt bei uns online statt. Im Seminar haben wir x Gruppenarbeiten geplant. Hier sollten diese 50 Teilnehmer in z.B. 5 Gruppen aufgeteilt werden. Klar, ich könnte nach und nach jeden Teilnehmer anklicken und jedem eine Gruppe zuweisen. Aber bei 50-100 Teilnehmer und mehr ist das sehr mühsam. 

    Ich habe gedacht, ich könnte nun im Vorfeld planen, wer später zu welcher Gruppe gehört um den jeweiligen Gruppen dann die unterschiedlichen Nachrichten zukommen lassen. 

    Die Ausgabe der Selection soll dann später so aussehen:

    Vorname Nachname Gruppe
    ---------------------------------------
    Max Mustermann 1
    Felix Schmidt 2
    Wolfgang Müller 3
    Erika Mustermann 4
    Luzie Schulte 5
    Lukas Müller 1
    ...

    Liebe Grüße, die Luzie!

    Mittwoch, 9. Dezember 2020 09:46
  • Eigentlich simpel:

    Du nummerierst die Zeilen per ROW_NUMBER.
    Die ROW_NUMBER multiplizierst du mit RAND().
    Das Ergebnis sortierst du aufsteigend und nimmst die TOP 50.

    Die ROW_NUMBER kannst du auch je Schlüssel gruppieren (Partition by).


    Mittwoch, 9. Dezember 2020 09:55
  • Hallo Luzie,

    probiers mal so:

    DECLARE @Teilnehmer TABLE( ID int NOT NULL, Vorname nvarchar( 50 ), Nachname nvarchar( 50 ), Gruppe int );
    
    INSERT INTO @Teilnehmer ( ID, Vorname, Nachname )
    VALUES ( 1, 'Max', 'Mustermann' ),
           ( 2, 'Felix', 'Schmidt' ),
           ( 3, 'Wolfgang', 'Müller' ),
           ( 4, 'Erika', 'Mustermann' ),
           ( 5, 'Luzie', 'Schulte' ),
           ( 6, 'Anton', 'Rößler' ),
           ( 7, 'Siegfried', 'Marx' ),
           ( 8, 'Wanda', 'Fisch' );
    
    WITH Query AS
    (
    SELECT ID,
           Vorname,
           Nachname,
           ROW_NUMBER() OVER( ORDER BY NEWID() ) AS RowNumber
    FROM   @Teilnehmer
    )
    SELECT ID,
           Vorname,
           Nachname,
           ( RowNumber % 5 ) AS Gruppe
    FROM   Query

    Beim nächsten mal bitte die Tabellendefinition und das INSERT Statement bitte selbst erzeugen. Dann können wir uns dem eigentlichen Problem schneller zuwenden.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    • Als Antwort markiert Luzie Samstag, 12. Dezember 2020 08:49
    Mittwoch, 9. Dezember 2020 10:02
    Moderator
  • Hallo

    vielen Dank für die Beispiele und den Tipp mit der Row_number() 

    Ja, die Statements erzeuge ich beim nächsten Mal selbst. 


    Liebe Grüße, die Luzie!

    Mittwoch, 9. Dezember 2020 15:37
  • Hallo Luzie,

    schau Dir bitte auch mal die Window Function NTILE an: NTILE (Transact-SQL)

    Damit kannst Du ganz einfach die Gruppen erzeugen. Falls im ORDER BY der vorgelagerten CTE etwas zufälliges steht (RAND liefert für alle die gleiche Zahl), dann kannst Du das für die Sortierung verwenden.

    DECLARE @Teilnehmer TABLE( ID int NOT NULL, Vorname nvarchar( 50 ), Nachname nvarchar( 50 ), Gruppe int );
    
    INSERT INTO @Teilnehmer ( ID, Vorname, Nachname )
    VALUES ( 1, 'Max', 'Mustermann' ),
           ( 2, 'Felix', 'Schmidt' ),
           ( 3, 'Wolfgang', 'Müller' ),
           ( 4, 'Erika', 'Mustermann' ),
           ( 5, 'Luzie', 'Schulte' ),
           ( 6, 'Anton', 'Rößler' ),
           ( 7, 'Siegfried', 'Marx' ),
           ( 8, 'Wanda', 'Fisch' );
    
    WITH Query AS
    (
    SELECT ID,
           Vorname,
           Nachname,
           cast(Vorname + Nachname as varbinary) as Sortierung
    FROM   @Teilnehmer
    )
    SELECT ID,
           Vorname,
           Nachname,
    	   Sortierung,
          NTILE(5) OVER(ORDER BY Sortierung) AS Gruppe
    FROM   Query
    ;
    

    HTH!


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu


    Donnerstag, 10. Dezember 2020 09:55
  • TSQL macht halt schon mal seltsame Dinge;-) im Vergleich zu anderen DB's.
    Alternativ geht auch:

    ABS(CHECKSUM(NewId())) % 50

    Das klappt zumindest je Zeile.

    Donnerstag, 10. Dezember 2020 10:51
  • Gute Idee, dann kombinieren wir das mal:

    	   RAND(Checksum(Newid())) as Sortierung


    Einen schönen Tag noch, Christoph - http://www.insidesql.org/blogs/cmu

    Freitag, 11. Dezember 2020 06:45
  • Hallo

    nochmals vielen Dank für die vielen Ideen. Ich werde es probieren. 


    Liebe Grüße, die Luzie!

    Samstag, 12. Dezember 2020 08:50