Ankündigung

Einklappen
Keine Ankündigung bisher.

Immer abwechselt Mann und Frau aus der Datenbank holen

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Immer abwechselt Mann und Frau aus der Datenbank holen

    Ich habe ein User Portal, dort stellen sich immer die neuersten Mitarbeiter in eine Liste mit 50 Einträge vor.
    In der Datenbank gibt es 1 Feld Geschlecht: 0= Mann, 1=Mädel.
    Gibt es ein Select wo man immer abwechselt ein Mann und eine Frau raus bekommen?

    Zurzeit hole ich die immer über 2 Abfragen raus, 25X Mann und 25X Frau.
    Über php wird das dann entsprechen kompliziert zusammen gefrimmelt

    Wenn Mysql die Logik übernimmt reicht eine PHP-Schleife aus.

    While ($rs=$resultat->fetch_object()){
    echo "<br> Name: $rs->vorname - $rs->name";
    }


    Betr. Mysql 5,6/PHP7
    Jemand eine super Idee?

  • #2
    Nur als Hinweis wie es gehen kann:

    Table:

    Code:
    CREATE TABLE gender
        (gender varchar(10))
    ;
    
    INSERT INTO gender
        (gender)
    VALUES
        ('male'),
        ('male'),
        ('male'),
        ('male'),
        ('male'),
        ('female'),
        ('female'),
        ('female'),
        ('female')
    ;
    Query:
    Code:
    select gender from 
    (select
      @x := @x +2 x,
      gender 
    from gender, (SELECT @x := 0) x
    where gender = 'male' limit 3
    union all
    select
      @y := @y +2 y,
      gender 
    from gender, (SELECT @y := 1) y
    where gender = 'female' limit 6
    ) z
    order by x;
    Output:

    Code:
    gender
    male
    female
    male
    female
    male
    female
    Wollte keine 50 Datensätze eingeben...

    Kommentar


    • #3
      uff, da muss ich morgen noch mal genauer drüber schauen, das sieht ja echt kompliziert aus. Ich denke jedoch, dass ich weiss was du da machst. Du vergibst eine Variable mit gerade und ungerade und sortierst dann anhand dieser Variablen, habe ich das so in etwa richtig interpretiert.

      Kommentar


      • #4
        ja, so ist es.

        Kommentar


        • #5
          Jetzt mal etwas ausführlicher, ich denke so ist es etwas verständlicher:

          Table:

          Code:
          CREATE TABLE members
              ( 
                firstName varchar(15),
                gender varchar(6),
                registerDate date
              );
          
          INSERT INTO members
              (
                firstName,
                gender,
                registerDate
              )
          VALUES
              ('Donald','male','2017-01-01'),
              ('Steve','male','2017-04-01'),
              ('Bill','male','2017-02-01'),
              ('Gerhard','male','2017-03-01'),
              ('Michaela','female','2017-06-01'),
              ('Angelika','female','2017-07-01'),
              ('Andrea','female','2017-03-01'),
              ('Susi','female','2017-02-01');
          Query:

          Code:
          select firstName, registerDate from
          (
            select * from
              (select
                @maleCount := @maleCount + 2 counter,
                firstname,
                registerDate
              from
                members, (SELECT @maleCount := 0) maleCount
              where
                gender = 'male'
              order by
                registerDate desc
              limit 2) males
          
              union all
          
              select * from
              (select
                @femaleCount := @femaleCount + 2 counter,
                firstname,
                registerDate
              from
                members, (SELECT @femaleCount := 1) femaleCount
              where
                gender = 'female'
              order by
                registerDate desc
              limit 2) females
              ) newRegistered
          order by counter
          Output:

          Code:
           
          Steve 2017-04-01
          Angelika 2017-07-01
          Gerhard 2017-03-01
          Michaela 2017-06-01

          Kommentar


          • #6
            Das ganze lässt sich auch ein wenig abkürzen, in dem man erst die Variablen setzt und die Sortierung des Datums vernachlässigt.
            Code:
            SET @femaleCount = -1;
            SET @maleCount = 0;
            
            select
                  @maleCount := @maleCount + 2 counter,
                  firstname,
                  registerDate
                from
                  members
                where
                  gender = 'male'
            union all
            select
                  @femaleCount := @femaleCount + 2 counter,
                  firstname,
                  registerDate
                from
                  members
                where
                  gender = 'female'
            ORDER BY counter

            Kommentar


            • #7
              ja, er wollte aber die 50 neuesten Mitglieder??

              Kommentar


              • #8
                ah ok, das habe ich dann wohl überlesen.

                Nun denn
                Code:
                SET @femaleCount = -1;
                SET @maleCount = 0;
                
                select
                    counter, `firstName`, `registerDate`
                from
                    (select
                          @maleCount := @maleCount + 2 counter,
                          firstname,
                          registerDate
                        from
                          members
                        where
                          gender = 'male'
                     ORDER BY `registerDate` DESC
                    ) males
                
                union all
                
                select
                    counter,`firstName`, `registerDate`
                from
                    (select
                      @femaleCount := @femaleCount + 2 counter,
                      firstname,
                      registerDate
                    from
                      members
                    where
                      gender = 'female'
                    ORDER BY `registerDate` DESC
                    ) females
                ORDER BY counter
                Limit 6
                viel gespart ist jetzt nicht, ist lediglich wegen der Übersichtlichkeit noch mal.

                Kommentar


                • #9
                  Tja, für das sich Anfangs keiner an eine Antwort getraut hat, können wir jetzt zufrieden sein

                  Kommentar


                  • #10
                    protestix

                    ich hatte mir nochmal Gedanken darüber gemacht warum ich eigentlich nicht mit SET gearbeitet habe. Man hat sich im Laufe der Jahre ein paar Eigenheiten angewöhnt und tippt diese ohne weiter darüber nachzudenken.

                    Jetzt habe ich es aber wieder, dies mache ich deswegen, weil ich die Abfrage immer wie folgt bearbeite:

                    PHP-Code:
                    $myResult $myQuery -> fetchAll(PDO::FETCH_ASSOC); 
                    oder welches fetch auch immer.

                    Dieses funktioniert aber nicht, wenn die query aus mehreren in sich abgeschlossenen Anweisungen besteht. In deinem Fall sind es 3 Anweisungen. Hier müsste dann ein "General Error" geschmissen werden.

                    Habe es nicht geprüft, aber im oberen dunklen Hinterstübchen schwirrt noch so etwas herum...


                    Kommentar


                    • #11
                      Habe mir schon gedacht, das da irgendwie eine Absicht dahinter steckt. Kann es sein das es mit PDO zu tun hat? Das fetchAll kanns ja nicht sein, Kommt ja nur ein Array bei rum. Ich habe da mal in der Doku gelesen das Multi statements von PDO nicht voll unterstützt wurden,aber keine Ahnung ob das damit zu tun hat.

                      Kommentar


                      • #12
                        Es hat schon etwas mit fetchAll zu tun

                        SET @femaleCount = -1; -> Record Count = 0...
                        SET @maleCount = 0; -> Record Count = 0...
                        select .... -> Record Count = 6
                        .....

                        demnach müsste man mit while PDO::nextRowset() arbeiten, das war mir dann doch zu aufwändig. Deswegen gestalte ich die selects immer so, dass nur eine Ergebnismenge zurück gegeben werden kann.

                        Kommentar


                        • #13
                          OK. Ich mache das mit Mysqli so
                          PHP-Code:
                          $res $mysqli->query("SET @femaleCount = -1;" );
                          $res $mysqli->query("SET @maleCount = 0;;" );
                          $res $mysqli->query($sql);

                          var_dump($res->fetch_all(MYSQLI_ASSOC)); 
                          Dann hat man zwar 3 Abfragen, aber das geht schnell und sollte nicht ins Gewicht fallen. Vorteil ist, man hat dann auch nur die Datensätze im Array stehen.

                          Kommentar


                          • #14
                            ja, so könnte man es mit PDO wohl auch gestalten...

                            Kommentar


                            • #15
                              Zitat von kaminbausatz Beitrag anzeigen
                              Tja, für das sich Anfangs keiner an eine Antwort getraut hat, können wir jetzt zufrieden sein
                              Jupp. Um Euch MySQL'ern etwas Hoffnung und Lichtblick zu geben bei diesem trüben Wetter, MySQL 8 wird dann auch Window-Funktionen können. Damit geht es einfacher:

                              Code:
                              log_repl_subscriber=# select * from namen ;
                                name   | m_w
                              ---------+-----
                               andreas | m
                               andrea  | w
                               anna    | w
                               liesa   | w
                               bernd   | m
                               hans    | m
                               lutz    | m
                              (7 rows)
                              
                              log_repl_subscriber=# select * from namen order by row_number() over (partition by m_w), m_w;
                                name   | m_w
                              ---------+-----
                               bernd   | m
                               liesa   | w
                               hans    | m
                               andrea  | w
                               lutz    | m
                               anna    | w
                               andreas | m
                              (7 rows)
                              PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                              Kommentar

                              Lädt...
                              X