MarkX: Abfrage-String für Anfangsbuchstaben

Moin,

ich habe ein Problem mit einer Datenbank-Abfrage. Da ich keine Idee habe wie ich dazu googlen soll, kommt hier meine Frage:

Ich möchte alle Datensätze haben, wo der Text in Feld "X" den Anfangsbuchstaben "A" hat. Ist sowas mit einer Abfrage möglich?
Falls ja, wie würde diese Abfrage dann aussehen?

MfG
MarkX.

  1. hi,

    ich habe ein Problem mit einer Datenbank-Abfrage. Da ich keine Idee habe wie ich dazu googlen soll, kommt hier meine Frage:

    Ich möchte alle Datensätze haben, wo der Text in Feld "X" den Anfangsbuchstaben "A" hat. Ist sowas mit einer Abfrage möglich?

    Ja.

    Falls ja, wie würde diese Abfrage dann aussehen?

    Schau dir den Operator LIKE in der Doku deines DBMS an.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. yo,

    Ich möchte alle Datensätze haben, wo der Text in Feld "X" den Anfangsbuchstaben "A" hat. Ist sowas mit einer Abfrage möglich?

    SELECT *
    FROM tabellen_name
    WHERE spalten_name LIKE 'A%'

    wobei noch darauf zu achten ist, ob du die abfrage unterscheiden lassen willst auf groos und kleinschreibung oder nicht.

    Ilja

  3. Danke für die beiden Antworten. Kurz nach meiner Fragestellung ist mir auch der Operator LIKE eingefallen. Naja, man sollte halt erst denken und dann fragen...

    MarkX.

    1. Danke für die beiden Antworten. Kurz nach meiner Fragestellung ist mir auch der Operator LIKE eingefallen. Naja, man sollte halt erst denken und dann fragen...

      Die schicken Stringfunktionen bieten sich auch an (MySQL vorausgesetzt): http://dev.mysql.com/doc/refman/5.1/de/string-functions.html

      LEFT() z.B..

      Mit dem BINARY-Operator (oder CAST()) kannst Du auch die "case sensitivity" zuschalten.

      http://dev.mysql.com/doc/refman/5.1/de/charset-binary-op.html

      1. yo,

        Die schicken Stringfunktionen bieten sich auch an (MySQL vorausgesetzt): http://dev.mysql.com/doc/refman/5.1/de/string-functions.html

        LEFT() z.B..

        in seinem falle ist der like operator die bessere wahl, es sei den mysql kennt schon funktionale indexe. aber selbst dann müsste extra dafür einer angelegt werden. also besser bei like bleiben.

        Ilja

        1. Die schicken Stringfunktionen bieten sich auch an (MySQL vorausgesetzt): http://dev.mysql.com/doc/refman/5.1/de/string-functions.html

          LEFT() z.B..

          in seinem falle ist der like operator die bessere wahl, es sei den mysql kennt schon funktionale indexe. aber selbst dann müsste extra dafür einer angelegt werden. also besser bei like bleiben.

          Erklär mal, LEFT(s, n) macht doch weniger als LIKE.

          1. yo,

            Erklär mal, LEFT(s, n) macht doch weniger als LIKE.

            das sieht auf den ersten blick so aus, auf den zweiten wird es aber unperformanter. dadurch das du eine funktion benutzt, wird eine vorhandener index auf dieser spalte nicht durch das dbms benutzt werden können. deshalb gibt es unter oracle und sicherlich auch anderen dbms funktionale indexe, sprich in diesem falle würdest du beim erzeugen des index nicht nur den spaltennamen angeben, sondern auch die funktion und zwar genauso, wie sie verwendent wird.

            der vorteil von LIKE 'A%' ist, dass ein schon bestehender index auf dieser spalte benutzt werden kann, nämlich der mir alle raussucht, die mit A anfangen, ich also kein extra funktionalen index anlegen muss und das nicht alle dbms disen überhaupt beherschen.

            Ilja

            1. Erklär mal, LEFT(s, n) macht doch weniger als LIKE.

              das sieht auf den ersten blick so aus, auf den zweiten wird es aber unperformanter. dadurch das du eine funktion benutzt, wird eine vorhandener index auf dieser spalte nicht durch das dbms benutzt werden können.

              Nun ja, ein eventuell vorhandener Index. Ist dieser nicht vorhanden, dann?

              der vorteil von LIKE 'A%' ist, dass ein schon bestehender index auf dieser spalte benutzt werden kann, nämlich der mir alle raussucht, die mit A anfangen,

              Ein Volltextindex?

              ich also kein extra funktionalen index anlegen muss und das nicht alle dbms disen überhaupt beherschen.

              Funktionale Indices kenne ich nicht, vermutlich meinst Du Indizes, die von besonders schlauen RDBMSen "auf Vorrat" angelegt werden, gerade wenn das SQL-Statement wg. Bekanntheit bereits vorkompiliert vorliegt? Wie würde das dann genau funktionieren? Wenn bspw. Datenänderungen anlagen?

              1. yo,

                Nun ja, ein eventuell vorhandener Index. Ist dieser nicht vorhanden, dann?

                dann ist das LIKE auch nicht langsamer, wenn aber einer vorhanden ist, ist es definitiv schneller. also nur vorteile.

                Ein Volltextindex?

                nein, wie kommst du darauf ? ich meinen einen ganz normalen b-tree index.

                Funktionale Indices kenne ich nicht, vermutlich meinst Du Indizes, die von besonders schlauen RDBMSen "auf Vorrat" angelegt werden, gerade wenn das SQL-Statement wg. Bekanntheit bereits vorkompiliert vorliegt?

                nein, indexe sollte grundsätzlich nicht aus vorrat angelegt werden, und auch hier muss der mensch noch hand anlegen.

                Wie würde das dann genau funktionieren? Wenn bspw. Datenänderungen anlagen?

                funktionale indexe funktionieren genauso wie ein normaler index, er wird bei datenbankänderungen on the fly nachgezogen.

                Ilja

                1. Nun ja, ein eventuell vorhandener Index. Ist dieser nicht vorhanden, dann?

                  dann ist das LIKE auch nicht langsamer, wenn aber einer vorhanden ist, ist es definitiv schneller. also nur vorteile.

                  Ist für uns nicht nachvollziehbar. Belege?

                  Wie würde das dann genau funktionieren? Wenn bspw. Datenänderungen anlagen?

                  funktionale indexe funktionieren genauso wie ein normaler index, er wird bei datenbankänderungen on the fly nachgezogen.

                  Funktionale Indizes sind Indizes, die das RDBMS an Hand spezieller Regeln selbstständig anlegt und verwaltet?

                  1. yo,

                    Ist für uns nicht nachvollziehbar. Belege?

                    test tabelle (string spalte) erstellen, eine millionen datensätze erzeugen, die nicht alle die gleichen werte haben, durch mehrfaches aufrufen von insert into test...select ..from test.., einmal mit der funktion aufrufen, einmal mit dem like, prüfen ob sie gleichschnell sind, index auf die spalte erzeugen, noch mal mit funktion und index ausführen, ausführungspläne anschauen, bzw. einfach die abfrage abfeuern.

                    Funktionale Indizes sind Indizes, die das RDBMS an Hand spezieller Regeln selbstständig anlegt und verwaltet?

                    selbständigt anlegt nein, verwaltet zum größten teil ja, wobei auch hier gilt, falls viele DML befehle ausgeführt wurden, ein rebuild oder drop and create zur wartung regelmäßig ausführen. eben genauso behandeln wie ein ganz normaler b-tree index.

                    Ilja

                    1. Ist für uns nicht nachvollziehbar. Belege?

                      test tabelle (string spalte) erstellen, eine millionen datensätze erzeugen, die nicht alle die gleichen werte haben, durch mehrfaches aufrufen von insert into test...select ..from test.., einmal mit der funktion aufrufen, einmal mit dem like, prüfen ob sie gleichschnell sind, index auf die spalte erzeugen, noch mal mit funktion und index ausführen, ausführungspläne anschauen, bzw. einfach die abfrage abfeuern.

                      Na, wenn das Belege sind. Aber ich werde gleich mal einen Haufen Zufallszahlen als VARCHAR in die DB hauen, sagen wir mal 1.000.000 Datensätze. Wie war noch mal Deine These? LIKE ist schneller, weil LIKE keine Funtion ist? Funktionen sind also mit grösserem Überbau implementiert. Gut, schaun mer mal.

                      1. T-SQL, MS SQL Server 2000, Windows 2003, mittelaltes Desktop-Gerät:

                          
                        -- Tabelle befüllen  
                        declare  
                         @i int  
                        set  
                         @i = 1  
                        while (@i <= 1000000)  
                         begin  
                         --  
                         insert  
                          DT_1  
                           (  
                           DF_1  
                           )  
                          VALUES  
                           (  
                           cast(@i as char(50))  
                           )  
                         set  
                          @i = @i + 1  
                         --  
                         end  
                        --  
                          
                        -- Abfrage mit left()  
                        declare  
                         @StartDate datetime  
                        declare  
                         @EndDate datetime  
                        set  
                         @StartDate = getdate()  
                        select  
                         count(*)  
                        from  
                         DT_1  
                        where  
                         (left(DF_1, 3) = '1')  
                        set  
                         @EndDate = getdate()  
                        print  
                         datediff(millisecond, @StartDate, @EndDate)  
                        --  
                          
                        -- Abfrage mit LIKE  
                        declare  
                         @StartDate datetime  
                        declare  
                         @EndDate datetime  
                        set  
                         @StartDate = getdate()  
                        select  
                         count(*)  
                        from  
                         DT_1  
                        where  
                         (DF_1 like '1%')  
                        set  
                         @EndDate = getdate()  
                        print  
                         datediff(millisecond, @StartDate, @EndDate)  
                        --  
                        
                        

                        LIKE gewinnt (ohne Index) in verschiedenen Varaiationen mit ca. 600ms gegen 500ms.  LOL

                        1. LIKE gewinnt (ohne Index) in verschiedenen Varaiationen mit ca. 600ms gegen 500ms.  LOL

                          LIKE gewinnt (ohne Index) in verschiedenen Variationen mit ca. 500ms gegen 600ms. Zudem in LEFT() einen Parameter korrigieren...

                          1. yo,

                            LIKE gewinnt (ohne Index) in verschiedenen Variationen mit ca. 500ms gegen 600ms. Zudem in LEFT() einen Parameter korrigieren...

                            das ist der erste teil der aussage, dass du mit LIKE keinen nachteil gegenüber LEFT hast, wenn kein index vorhanden ist. hast du den schon einen index über die spalte angelegt und dann nochmals beide abfragen ausgeführt und die zeiten verglichen ?

                            Ilja

                            1. LIKE gewinnt (ohne Index) in verschiedenen Variationen mit ca. 500ms gegen 600ms. Zudem in LEFT() einen Parameter korrigieren...

                              das ist der erste teil der aussage, dass du mit LIKE keinen nachteil gegenüber LEFT hast, wenn kein index vorhanden ist.

                              LOL - anders sieht es gegen RIGHT() aus:

                                
                              -- RIGHT(LTRIM(RTRIM())) gewinnt gegen  
                              declare  
                               @StartDate datetime  
                              declare  
                               @EndDate datetime  
                              set  
                               @StartDate = getdate()  
                              select  
                               count(*)  
                              from  
                               DT_1  
                              where  
                               (right(ltrim(rtrim(DF_1)), 4) = '1134')  
                              set  
                               @EndDate = getdate()  
                              print  
                               datediff(millisecond, @StartDate, @EndDate)  
                              --  
                                
                              -- LIKE in diesem Beispiel (wir haben ein CHAR(50))  
                              declare  
                               @StartDate datetime  
                              declare  
                               @EndDate datetime  
                              set  
                               @StartDate = getdate()  
                              select  
                               count(*)  
                              from  
                               DT_1  
                              where  
                               (DF_1 like '%1134')  
                              set  
                               @EndDate = getdate()  
                              print  
                               datediff(millisecond, @StartDate, @EndDate)  
                              --  
                                
                              -- mit ca. 750ms gegen ca. 13300ms  
                              
                              

                              Soweit zu "keine Nachteile".

                              hast du den schon einen index über die spalte angelegt und dann nochmals beide abfragen ausgeführt und die zeiten verglichen ?

                              Moment, mach ich jetzt, hab ein wenig Zeit, OK, Index da, keine signifikanten Änderungen bei o.g. Abfrage. - Bei der zuerst untersuchten Abfrage mit LEFT(), Moment: Da braucht LEFT() immer noch ca. 600ms, LIKE "unfassbare und superüberraschende" 0ms.   ;)

                              OK, liegt halt ein Index drauf und der Mist ist vorsortiert, ein Wert zwischen 20ms und 100ms wäre aber schon anstandsgemässer gewesen.

                              Ja, gut, halten wir das Resultat fest:

                              • LIKE ist im Durchschnitt langsamer als die Verwendung von Funktionen, wenn kein Index vorliegt
                              • LIKE ist sehr viel schneller, wenn ein INDEX vorliegt, der "genau die Abfrage trifft", ansonsten durchschnittlich langsamer (siehe Anlage)

                              Wer Lust hat kann die Performancemessungen mit T-SQL unter MS SQL Server so zu sagen jederzeit reproduzieren.

                              Anlage:

                                
                              declare  
                               @StartDate datetime  
                              declare  
                               @EndDate datetime  
                              set  
                               @StartDate = getdate()  
                              select  
                               count(*)  
                              from  
                               DT_1  
                              where  
                               (DF_1 like '1345%')  
                              set  
                               @EndDate = getdate()  
                              print  
                               datediff(millisecond, @StartDate, @EndDate)  
                                
                              -- mit Index 0ms bei 1.000.000 Datensätzen und CHAR(50)-Feldern  
                              
                              
                                
                              declare  
                               @StartDate datetime  
                              declare  
                               @EndDate datetime  
                              set  
                               @StartDate = getdate()  
                              select  
                               count(*)  
                              from  
                               DT_1  
                              where  
                               (DF_1 like '%1345%')  
                              set  
                               @EndDate = getdate()  
                              print  
                               datediff(millisecond, @StartDate, @EndDate)  
                                
                              -- mit Index 14400ms bei 1.000.000 Datensätzen und CHAR(50)-Feldern  
                              
                              
                              1. yo,

                                wenn du verstehen würdest, warum LIKE mit dem index so viel schneller gegenüber der funktion ist, dann würdest du auch diesen vergleich mit right und like nicht machen, weil:

                                like '%1134' ist etwas vollkommen anderes als like 'A%'

                                und wenn du weiter oben schaust, dann schrieb ich in seinem Falle ist es besser beim like zu bleiben. warum das so ist, kann gerne jemand anders versuchen zu erklären.

                                Ilja

                                1. Aus Genussgründen versuchen wir mal zu rekapitulieren, was an der Diskussion schief lief:

                                  1.) die Frage:

                                  ich habe ein Problem mit einer Datenbank-Abfrage. Da ich keine Idee habe wie ich dazu googlen soll, kommt hier meine Frage:

                                  Ich möchte alle Datensätze haben, wo der Text in Feld "X" den Anfangsbuchstaben "A" hat. Ist sowas mit einer Abfrage möglich?
                                  Falls ja, wie würde diese Abfrage dann aussehen?

                                  [http://forum.de.selfhtml.org/?t=144856&m=939724]

                                  Kommentar: beliebiges DF, von Index keine Spur

                                  2.) Meine Antwort:

                                  Die schicken Stringfunktionen bieten sich auch an (MySQL vorausgesetzt): http://dev.mysql.com/doc/refman/5.1/de/string-functions.html [...]

                                  https://forum.selfhtml.org/?t=144856&m=939784

                                  Kommentar: Hinweis auf Stringfunktionen, nachdem Dritte richtigerweise bereits den LIKE-Operator in die Diskussion eingebracht haben

                                  3.) Deine Nachricht:

                                  in seinem falle ist der like operator die bessere wahl, es sei den mysql kennt schon funktionale indexe. aber selbst dann müsste extra dafür einer angelegt werden. also besser bei like bleiben.

                                  https://forum.selfhtml.org/?t=144856&m=939854

                                  Kommentar: Deine Thesen lautet: mit Index ist LIKE schneller, da LIKE im Gegensatz zu LEFT() den Index referenziert.
                                  Dem wollten wir eigentlich nie widersprechen, in der Folge...

                                  4.) Meine Nachricht:

                                  in seinem falle ist der like operator die bessere wahl, es sei den mysql kennt schon funktionale indexe. aber selbst dann müsste extra dafür einer angelegt werden. also besser bei like bleiben.

                                  Erklär mal, LEFT(s, n) macht doch weniger als LIKE.

                                  https://forum.selfhtml.org/?t=144856&m=939864

                                  Kommentar: Und die Missverständnisse nehmen ihren Lauf.

                                  Also, zusammenfassend, wenn Index da, der sinnvoll referenziert werden kann, dann den Operator LIKE nutzen, ansonsten besser auf die Stringfuntionen zurückgreifen wegen geringerem Überbau.

                                  1. yo,

                                    Also, zusammenfassend, wenn Index da, der sinnvoll referenziert werden kann, dann den Operator LIKE nutzen, ansonsten besser auf die Stringfuntionen zurückgreifen wegen geringerem Überbau.

                                    und wo hat der like 'A%' mehr zeit gebraucht als die left funktion ohne index, warum sollte dabei die left funktion besser sein ?

                                    und welche spalten werden üblicherweise mit einem index belegt ?

                                    die zusammenfassung ist: like 'A%' ist nicht langsamer als die funktion und deutlich schneller mit einem index. ich glaube, ein blinder würde das sehen, wenn er den wollte.

                                    Ilja

                                    1. die zusammenfassung ist: like 'A%' ist nicht langsamer als die funktion und deutlich schneller mit einem index. ich glaube, ein blinder würde das sehen, wenn er den wollte.

                                      Belassen wir es bei diesem Dissenz. Nächstes Mal wäre etwas mehr Empathie unserseits vielleicht sinnvoll.

                                      Wobei uns die Performance-Vergleiche LIKE vs. Stringfuntionen aber entgangen wären.   ;)

                                      1. yo,

                                        noch ein hinweis, auf deinen vergleich mit der right funktion und dem like '%1234'. in diesem fall kann und darf der like gar nicht schneller sein, weil er viel mehr leistet.

                                        dies ist ganz einfach nachzuprüfen, weil die ergebnismenge deiner right funktion eine andere ist, als die mit like. und wenn du zwei ganz unterschiedliche ergebnismengen auf den gleichen datenbestand bekommst (mal spezielle fälle wie leere tabellen und keine wirkliche verteilung abgesehen), dann kann man das nicht miteinander vergleichen. viele verschiedene abfragen führen 1:1 zum gleichen ergebnis und diese lassen sich dann auch hinsichtlich der ausführungsgeschwindigkeit gut miteinander vergleichen. dein beispiel mit right und like ist es aber nicht. insofern hat es gar keinen sinn gemacht, es anzuführen.

                                        versuche zu verstehen, wie like funktioniert und du wirst mit der like klausel einen neuen freund gewinnen und warum er in bestimmten fällen den funktionen vorzuziehen ist.

                                        Ilja

                      2. Wie war noch mal Deine These? LIKE ist schneller, weil LIKE keine Funtion ist?

                        Nein, war nicht seine These.

                        der vorteil von LIKE 'A%' ist, dass ein schon bestehender index auf dieser spalte benutzt werden kann, ....

                        https://forum.selfhtml.org/?t=144856&m=939958

                        dann ist das LIKE auch nicht langsamer, wenn aber einer vorhanden ist, ist es definitiv schneller. also nur vorteile.

                        Wenn ich das richtig sehe, ist das genau was du belegt hast, oder?

                        Struppi.

                        --
                        Javascript ist toll (Perl auch!)
                        1. Wie war noch mal Deine These? LIKE ist schneller, weil LIKE keine Funtion ist?

                          Nein, war nicht seine These.

                          Anscheinend war das schon seine These, die zudem richtig zu sein scheint. (Wir werden allerdings spasseshalber bei späterer Gelegenheit noch ein wenig auf den erzeugten Daten herumhühnern um aussagekräftigere Messergebnisse zu erhalten.)

                          Ilja argumentiert immer wieder mit einem Index, der uns allerdings erst einmal überhaupt nicht interessiert. Vielleicht war darum der Diskurs ein wenig unklar.

                          Eine Vermutung warum LIKE schneller ist als bspw. LEFT() ist natürlich, dass LIKE direkt auf den zu vergleichenden String geht und den von links nach rechts durchforscht und ggf. früh abbricht, LEFT() beisst immer ein Stück vom Kuchen ab und braucht einen neuen Speicherbereich für den Abbiss.

                          https://forum.selfhtml.org/?t=144856&m=939958

                          dann ist das LIKE auch nicht langsamer, wenn aber einer vorhanden ist, ist es definitiv schneller. also nur vorteile.

                          Wenn ich das richtig sehe, ist das genau was du belegt hast, oder?

                          Bisher ja, klar.

                          1. yo,

                            Ilja argumentiert immer wieder mit einem Index, der uns allerdings erst einmal überhaupt nicht interessiert.

                            der ursprung der diskussion liegt darin, dass du von mir wissen wolltest, warum LIKE besser ist als eine funktion. und der grund dafür ist eben der index und dessen einsatz. deswegen interessiert er schon die ganzr zeit, genau dort liegt der vorteil von LIKE gegenüber einer funktion.

                            Eine Vermutung warum LIKE schneller ist als bspw. LEFT() ist natürlich, dass LIKE direkt auf den zu vergleichenden String geht und den von links nach rechts durchforscht und ggf. früh abbricht, LEFT() beisst immer ein Stück vom Kuchen ab und braucht einen neuen Speicherbereich für den Abbiss.

                            darum geht es nicht, ohne index sind sowohl der weg mit LIKE als auch der weg mit der funktion ungefähr gleich schnell. kleine abweischung sind dabei geschenkt.

                            wenn es dich wirklich interessiert, leg den index an und führe beide abfragen noch einmal aus.

                            Ilja

                            1. der ursprung der diskussion liegt darin, dass du von mir wissen wolltest, warum LIKE besser ist als eine funktion.

                              Was uns an solchen Leuten wie Dich nervt ist, dass Du sehr oft zu wissen meinst, was der Fragesteller wirklich wissen will (noch zu verkraften) und dann in der Folge dem Fregsteller bei Richtigstellungen widersprichst, das aber ist kindisch.

                              darum geht es nicht, ohne index sind sowohl der weg mit LIKE als auch der weg mit der funktion ungefähr gleich schnell. kleine abweischung sind dabei geschenkt.

                              Dir mag das egal sein, uns dagegen interessiert es.

                              1. yo,

                                dass Du sehr oft zu wissen meinst, was der Fragesteller wirklich wissen will

                                Zitat von dir: "Erklär mal, LEFT(s, n) macht doch weniger als LIKE."

                                dann solltest du dich mal entscheiden, ob du es nun erklärt haben willst oder nicht. wenn es dich von der sache wirklich interessiert, gerne. wenn du nur ärgern und provozieren willst, dann sag es doch einfach. dann kann sich jeder darauf einlassen, der lust dazu hat.

                                Ilja

                                1. dass Du sehr oft zu wissen meinst, was der Fragesteller wirklich wissen will

                                  Zitat von dir: "Erklär mal, LEFT(s, n) macht doch weniger als LIKE."

                                  Ja, sowas hat uns interessiert, wie LIKE implementiert ist. Grundannahme hier: LIKE hat grösseren Überbau und ist langsamer.

                                  dann solltest du dich mal entscheiden, ob du es nun erklärt haben willst oder nicht.

                                  Deine "Erklärungen" sind ja etwas dünn.   ;)

                                  wenn es dich von der sache wirklich interessiert, gerne. wenn du nur ärgern und provozieren willst, dann sag es doch einfach. dann kann sich jeder darauf einlassen, der lust dazu hat.

                                  Wir glauben nun mal nicht viel von dem üblichen Gesülze (gerade Deins nicht), der Mensch irrt traditionell zu oft, jeder auch nur etwas komplexe Sachverhalt birgt den Irrtum, darum haben wir ja auch fleissig gemessen, u.a. hier wieder:

                                  https://forum.selfhtml.org/?t=144856&m=940294