nobbi: Verschachtelte WHERE Abfragen Mysql

Hallo,

irgendwie raffe ich das mit den verschachtelten WHERE Abfragen nicht.

Aufgabe

Ich habe eine Tabelle mit den Spalten plz, ort, strasse usw. Durch die Strassen kommen natürlich die Orte x fach vor.

Ich brauche jetzt eine Abfrage die plz nur einmal ergibt.

Mit SQL DISTINCT plz FROM tabelle WHERE ort LIKE "Dresden".

Habe ich im Ergebnis auch nur die plz, nicht aber die Ortsnamen. Ich bräuchte aber etwa folgendes Ergebnis:

plz = 01067 , ort = Dresden
plz = 01068 , ort = Dresden
plz = 01069 , ort = Dresden

usw. Demnach muss ich wohl eine 2. WHERE Klausel einfügen. Aber wie?

Ich raffs nicht!

  1. Hi,

    Mit SQL DISTINCT plz FROM tabelle WHERE ort LIKE "Dresden".

    Habe ich im Ergebnis auch nur die plz, nicht aber die Ortsnamen.

    Wieso sollten da Ortsnamen kommen?

    Du selektierst doch nur die PLZ (ich gehe mal davon aus, daß das 'SQL' eigentlich ein 'SELECT' sein soll.

    Ich bräuchte aber etwa folgendes Ergebnis:

    plz = 01067 , ort = Dresden plz = 01068 , ort = Dresden plz = 01069 , ort = Dresden

    Dann müßtest Du einen String 'plz = ' mit der Spalte plz und einem String ' , ort = ' und der Spalte ort concateniert auswählen.

    Demnach muss ich wohl eine 2. WHERE Klausel einfügen.

    Wieso?

    1. kann ein SELECT nur ein WHERE enthalten (außer in subselects),
    2. stimmt doch die Auswahl der Zeilen, nur das aus den Zeilen gewählte paßt Dir noch nicht.

    cu,
    Andreas a/k/a MudGuard

    1. Sorry, natürlich SELECT, nicht SQL.

      Aber Containert? Gibts das auch in Deutsch, bezogen auf das SELECT? Evtl. mit Beispiel?

      1. Hallo nobbi,

        nein, nicht containert. Lies genau: con cat e niert. Abgeleitet ist das von der CONCAT Funktion zur Stringverkettung.

        Evtl. mit Beispiel?

        Brauchst Du tatsächlich die Textstücke "plz =" und "ort =" in der Ausgabe? Wenn ja, warum? Sowas macht man normalerweise nicht, eine visuelle Aufbereitung ist Aufgabe der Anwendung, die auf die Datenbank zugreift. Wenn Du mit Tools wie MySQL Workbench oder phpMyAdmin auf die Tabelle zugreifst, bekommst Du ohnehin eine Spaltenaufbereitung der Anzeige mit Überschriften.

        Das Beispiel findest Du dann im Handbuch zu MySQL.

        Rolf

        --
        sumpsi - posui - obstruxi
  2. Oh Gott, jetzt hats mir die Formatierung etwas verhunzt. Ich hoff mein Problem kommt trotzdem rüber.

  3. Hallo nobbi,

    wenn dein Problem exakt so wie beschrieben ist, musst Du den Ort einfach nur in die SELECT Liste aufnehmen.

    SELECT DISTINCT plz, ort FROM tabelle WHERE ort LIKE "Dresden".
    

    Die Verwendung von LIKE ist hier übrigens wenig sinnvoll. LIKE verwendet man, wenn man Mustersuche betreiben will (also z.B. ort LIKE "Dresden%", um alle Ortsnamen zu finden die mit Dresden beginnen).

    Für einen normalen Vergleichstest nimmt man den = Operator. Der hat auch den Vorteil, abschließende Leerstellen nicht zu beachten. Wenn dein Ort also keine varchar-Spalte ist, sondern feste Breite hat, dann steht da nicht "Dresden" drin, sondern - wenn die Breite bspw. 15 wäre -

    "Dresden        "
    

    Dein Like-Vergleich würde da fehlschlagen (@Christian Kruse, wieso hat das code-Element nicht white-space: pre-wrap als Eigenschaft?)

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      weil es overflow-x: scroll hat.

      Freundliche Grüße,
      Christian Kruse

    2. Hallo Rolf B,

      (@Christian Kruse, wieso hat das code-Element nicht white-space: pre-wrap als Eigenschaft?)

      Ein

      code.block {
        white-space: pre-wrap;
        overflow-x: auto;
      }
      

      wäre vielleicht tatsächlich günstiger. Mach doch mal einen Pull-Request. Ich pack das solange mal im mein user-css. Vielleicht fallen mir ja Ungereimtheiten auf.

      Bis demnächst
      Matthias

      --
      Du kannst das Projekt SELFHTML unterstützen,
      indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
      1. Hallo Matthias,

        Ein

        code.block {
          white-space: pre-wrap;
          overflow-x: auto;
        }
        

        wäre vielleicht tatsächlich günstiger.

        Nein. Das hatten wir bereits. Wir haben es geändert, weil es dazu immer wieder… „Rückmeldungen“ gab.

        Freundliche Grüße,
        Christian Kruse

        1. Hallo Christian Kruse,

          Nein. Das hatten wir bereits. Wir haben es geändert, weil es dazu immer wieder… „Rückmeldungen“ gab.

          Ja, ich erinnere mich. „Die Zeilenumbrüche stimmen überhaupt nicht mehr.“ Aber overflow-x: auto sollte doch auch keinen Schaden anrichten. Oder wird das code-Element dann wieder breiter als der Beitrag?

          Bis demnächst
          Matthias

          --
          Du kannst das Projekt SELFHTML unterstützen,
          indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
          1. Hallo Matthias,

            Oder wird das code-Element dann wieder breiter als der Beitrag?

            Ja 😉

            Freundliche Grüße,
            Christian Kruse

            1. Hallo Christian,

              so hab ich's in meinem User-CSS für code.block gemacht. Da ist overflow:visible drin, und da setzt Du white-space:pre auch. Aber braucht es das? Du packst Block-Code ohnehin in ein <pre> Element, da erbt es diese Einstellung ohnehin.

              Aber ich sprach auch gar nicht davon, sorry, hätte ich sagen sollen. Ich sprach von code:not(.block), also Inline-Code. Ich wollte zeigen, dass hinter Dresden mehrere Leerstellen kommen können, so: "Dresden " - und diese Leerstellen kollabieren.

              code:not(.block) {
                 white-space:pre;
              } 
              

              könnte da helfen.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Hallo Rolf,

                Aber braucht es das? Du packst Block-Code ohnehin in ein <pre> Element, da erbt es diese Einstellung ohnehin.

                Zufall. Da hat sich der Markdown-Renderer geändert, anfangs hat er kein <pre> gesetzt.

                Aber ich sprach auch gar nicht davon, sorry, hätte ich sagen sollen. Ich sprach von code:not(.block), also Inline-Code. Ich wollte zeigen, dass hinter Dresden mehrere Leerstellen kommen können, so: "Dresden " - und diese Leerstellen kollabieren.

                Ah, das ist vermutlich ein Bug. Mach doch bitte ein Ticket.

                Freundliche Grüße,
                Christian Kruse

                1. Hallo Christian,

                  Mach doch bitte ein Ticket.

                  Done. Ich würd's ja auch als pull request vorbereiten, weiß aber nicht genau wie Du die Regeln strukturierst.

                  Nach code,kbd hinein und von code.block überschreiben lassen?
                  Eigene Regel für code, weil es für kbd nicht relevant ist (aber kbd ist eh nicht relevant, du verwendest es dem Anschein nach nicht)?
                  Eigene Regel mit code:not(.block) Selektor?

                  Mach mal lieber selber 😉

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Hallo Rolf,

                    Mach doch bitte ein Ticket.

                    Done.

                    Danke 😀

                    Nach code,kbd hinein und von code.block überschreiben lassen?

                    Ja, das würde ich gerade tun.

                    Eigene Regel für code, weil es für kbd nicht relevant ist (aber kbd ist eh nicht relevant, du verwendest es dem Anschein nach nicht)?

                    kbd ist nur der Vollständigkeit halber drin. Es gibt mehrere Stellen im Forum, wo auch HTML eingegeben werden kann (z.B. im Weblog oder der MOTD), da wollte ich bei Verwendung einen Style dafür haben

                    Mach mal lieber selber 😉

                    Heute Abend, nach meiner Erwerbstätigkeit.

                    Freundliche Grüße,
                    Christian Kruse

            2. Hallo Christian Kruse,

              Oder wird das code-Element dann wieder breiter als der Beitrag?

              Ja 😉

              Nö?

              #myID {
                background-image { url("https://example.com/bild/mit/einem/ganz/langen/pfad/example.png");
              }
              

              Screenshot code-Block mit overflow-x: auto

              Bis demnächst
              Matthias

              --
              Du kannst das Projekt SELFHTML unterstützen,
              indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
              1. Hallo Matthias,

                Oder wird das code-Element dann wieder breiter als der Beitrag?

                Ja 😉

                Nö?

                Du sprachst davon, overflow-x zu ändern. In deinem Screenshot hast du auch white-space geändert.

                Ich möchte das nicht schon wieder ändern. Wir hatten das mit pre-wrap, wir haben uns bewusst dagegen entschieden. Bitte nicht ständig hin und her. 😉

                Freundliche Grüße,
                Christian Kruse

                1. Hallo Christian Kruse,

                  Ich möchte das nicht schon wieder ändern. Wir hatten das mit pre-wrap, wir haben uns bewusst dagegen entschieden. Bitte nicht ständig hin und her. 😉

                  Es sollte auch so bleiben. Ich habe mir gestern abend einige Beiträge am Handy angeschaut und werde mein User-CSS auch wieder zurück ändern. Die Lesbarkeit mit pre-wrap leidet. Aber im Alter vergisst man hin und wieder auch, was wir genau geändert hatten.

                  Bis demnächst
                  Matthias

                  --
                  Du kannst das Projekt SELFHTML unterstützen,
                  indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
                  1. Hallo Matthias,

                    Aber im Alter vergisst man hin und wieder auch, was wir genau geändert hatten.

                    No hard feelings, wie die Engländer sagen. Ich vergesse auch so manches, deshalb wollte ich einfach nur die Erinnerung wachrütteln 😉

                    Freundliche Grüße,
                    Christian Kruse

    3. Wenns so einfach ist, hab ich mal wieder viel zu kompliziert gedacht. Ich bin davon ausgegangen, dass mehrere Angaben nach DISTINCT sich auf eben dieses beziehen, also auf Eindeutigkeit geprüft wird.

      Zum LIKE

      Dass an meinem Beispiel LIKE nicht das richtige ist, ist mir klar. In der Realität wäre der Suchbegriff z.B. "Dresd%".

      Aber vielen Dank.

      1. Hallo Nobbi,

        Wenns so einfach ist, hab ich mal wieder viel zu kompliziert gedacht. Ich bin davon ausgegangen, dass mehrere Angaben nach DISTINCT sich auf eben dieses beziehen, also auf Eindeutigkeit geprüft wird.

        Das ist auch so:

        SELECT DISTINCT plz, ort FROM `table` WHERE 1
        

        sollte alle Einträge von plz und ort genau einmal liefern.

        PLZ_1, Ort_1
        PLZ_1, Ort_2 
        
        PLZ_2, Ort_1
        

        Bis demnächst
        Matthias

        --
        Du kannst das Projekt SELFHTML unterstützen,
        indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
        1. Und was mach ich dann, wenn ich nur auf Einmaligkeit der PLZ suche, aber alle Felder die an dem gefundenen Datensatz hängen brauche?

          1. Hallo Nobbi,

            Und was mach ich dann, wenn ich nur auf Einmaligkeit der PLZ suche, aber alle Felder die an dem gefundenen Datensatz hängen brauche?

            Das ist ein Widerspruch: Wenn es eine PLZ in mehreren Datensätzen gibt, kannst du nicht von dem gefundenen Datensatz sprechen. Versuch doch mal zu beschreiben, welche Daten du haben möchtest.

            Bis demnächst
            Matthias

            --
            Du kannst das Projekt SELFHTML unterstützen,
            indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
            1. Hi,

              Und was mach ich dann, wenn ich nur auf Einmaligkeit der PLZ suche, aber alle Felder die an dem gefundenen Datensatz hängen brauche?

              Das ist ein Widerspruch: Wenn es eine PLZ in mehreren Datensätzen gibt, kannst du nicht von dem gefundenen Datensatz sprechen. Versuch doch mal zu beschreiben, welche Daten du haben möchtest.

              Um's noch konkreter zu sagen: es gibt PLZ, zu denen es mehrere Ortsnamen gibt.

              Beispiel:
              82152 Martinsried
              82152 Planegg
              82152 Krailling

              cu,
              Andreas a/k/a MudGuard

          2. Hallo Nobbi,

            wenn Du mit einem SELECT DISTINCT beispielsweise 10117 Berlin bekommst, dann können dahinter viele Datensätze liegen, deren Inhalte aber unterschiedlich sind.

            Zum Beispiel Pariser Platz 2 (USA Konsulat), Unter den Linden 77 (Hotel Adlon) oder Unter den Linden 78 (Dunkin' Donuts gleich gegenüber).

            Was willst Du da denn ausgeben?

            Wenn Du eine Abfrage haben willst, die dir alle Sätze auflistet, die vom SELECT DISTINCT zusammengefasst wurden, dann brauchst Du tatsächlich eine Schachtelung und einen JOIN. Ich zeige ihn zwar mal vor, aber verwende ihn bitte nur, um den DB-Server zum Rösten von Popcorn auf Betriebstemperatur zu bringen - denn das gleiche Ergebnis bekommst schneller, wenn Du einfach nur in der Adressentabelle nach ort="Berlin" suchst. Eine Query dieser Art ist sinnvoll, wenn die DISTINCT-Query nicht nach dem Ort sucht, sondern nach irgendwas anderem. Wenn Du alle Adressen aus den PLZ-Bereichen willst, wo ein Mensch namens "Müller" wohnt, zum Beispiel. Das wäre was für eine Rasterfahndung...

            SELECT a.name, a.vorname, a.plz, a.ort, a.anschrift
            FROM (SELECT DISTINCT plz, ort 
                      FROM adressen 
                      WHERE ort = 'Berlin') d
                 JOIN adressen a ON a.plz = d.plz AND a.ort = d.ort
            

            JOIN kennst Du vielleicht, damit verknüpft man zwei Tabellen über gemeinsame Spaltenwerte. Normalerweise schreibt man da sowas wie table1 JOIN table2 ON ..., aber das Ergebnis eines SELECT ist ebenfalls eine Table und kann deshalb in einem Join genauso verwendet werden.

            Diese Query geht sozusagen in zwei Schritten vor. Im ersten Schritt werden alle Postleitzahlen gesucht, die zu Berlin gehören. Das ergibt eine temporäre Tabelle aus einigen Zeilen und 2 Spalten: plz und ort. Im zweiten Schritt wird diese temporäre Tabelle mit der Adressen-Table geJOINt und für jeden Satz in der temporären Tabelle die Adressen herausgesucht, die diese PLZ und diesen Ort haben.

            Weil nun die gleichen Spaltennamen (plz und ort) mehrfach vorkommen, bekommen die Abfrageergebnisse Aliasnamen. Das ist das a und das d, was hinter der DISTINCT-Abfrage und hinter der geJOINten Adressentabelle steht. Diese Aliasnamen werden dann verwendet, um anzugeben, aus welcher Tabelle man PLZ oder ORT haben will.

            Rolf

            --
            sumpsi - posui - obstruxi