Markus: Abfrage in ANSI SQL umschreiben

Hallo!

Kann mir vielleicht jemand bei folgendem Beispiel weiterhelfen.

Ich soll alle Angestellten anzeigen deren Nachname mit „J“, „K“, „L“ oder  „M“ beginnt.

Ich habe die Aufgabe schon gelöst, aber ich habe sie nicht in ANSI SQL Geschrieben.

select last_name
from   employees
where  last_name like 'J%'
or     last_name like 'K%'
or     last_name like 'L%'
or     last_name like 'M%'

Ich habe schon viele Variationen versucht, aber ich erhalte immer Fehlermeldungen oder bekomme kein Ergebnis ausgegeben, also eine leere Tabelle.
Wenn ich zum Beispiel folgendes versuche, erhalte ich nur die Meldung „Rechte Klammer fehlt!“

select last_name
from   employees
where  last_name like ('J%', 'K%', 'L%', 'M%')

Vielleicht kann mir ja jemand weiterhelfen?

Übrigens! Ich verwende eine Oracle 10g Datenbank.

Liebe Grüße
Markus

  1. yo,

    Ich habe die Aufgabe schon gelöst, aber ich habe sie nicht in ANSI SQL Geschrieben.

    ich wüßte nicht, warum deine abfrage nicht nach ANSI SQL gültig sein soll.

    Ich habe schon viele Variationen versucht, aber ich erhalte immer Fehlermeldungen oder bekomme kein Ergebnis ausgegeben, also eine leere Tabelle.

    ohne diese varianten zu kennen, ist es schwierig zu helfen.

    Wenn ich zum Beispiel folgendes versuche, erhalte ich nur die Meldung „Rechte Klammer fehlt!“

    LIKE kanst du auch nicht mit dem IN operator verbinden, zumindestens ist mit das in Oracle nicht bekannt. aber ein kleiner tipp noch, Oracle unterscheidet zwischen klein und grossschreibung, was mssql zum beispiel nicht macht. Also LIKE 'M%' ist was anderes als LIKE 'm%' in oracle.

    Ilja

    1. Hallo!

      Also mir ist gesagt worden,  dass dieses Beispiel nochmals machen soll und dabei ANSI SQL verwenden soll.

      Hier noch ein paar andere Versuche:

      1.
      select last_name
      from   employees
      where  last_name like 'J%', 'K%', 'L%', 'M%'

      Fehlermeldung: “SQL Befehl wurde nicht korrekt beendet!”

      2.
      select last_name
      from   employees
      where  last_name like ('J%', 'K%', 'L%', 'M%')

      Fehlermeldung: ”Rechte Klammer fehlt!”

      3.
      select last_name
      from   employees
      where  last_name like ('J%'), ('K%'), ('L%'), ('M%')

      Fehlermeldung: “SQL Befehl wurde nicht korrekt beendet!”

      Liebe Grüße,
      Markus

      1. Hallo!

        Hier noch ein Versuch:

        select last_name
        from   employees
        where  last_name in ('J%')('K%')('L%')('M%')

        Fehlermeldung: „Funktion nicht implementiert!“

        Liebe Grüße,
        Markus

        1. Dann lies doch bitte endlich mal die Dokumentation von Oracle 10g/11g zum Thema

          • welche Zeichenkettenoperationen gibt es
          • welche Vergleichsoperationen gibt es

          Du zeigst zum 3. Mal absoluten Unwillen zur Eigeninitiative. Wie willst du die Materie lernen und verstehen wenn du dir jedes mal die Ergebnisse vorkauen lässt?

          An Iljas oder Vinzenz's Stelle würde ich dir nicht mehr weiterhelfen.

          Ciao, Frank

  2. Hallo

    Kann mir vielleicht jemand bei folgendem Beispiel weiterhelfen.

    Ich soll alle Angestellten anzeigen deren Nachname mit „J“, „K“, „L“ oder  „M“ beginnt.

    Ich habe die Aufgabe schon gelöst, aber ich habe sie nicht in ANSI SQL Geschrieben.

    Habt Ihr einen Auszug, Übersicht oder was auch immer über den zu verwendenden ANSI-SQL-Standard (es gibt übrigens verschiende, je nach Jahr des Standards) bekommen? Die SQL-Spezifikation kostet, soweit ich gehört habe, Geld, richtig Geld. Keiner meiner bisherigen Arbeitgeber hat es für nötig erachtet, dieses zu investieren - auch wenn das Hauptprodukt eine SQL-basierte Anwendung war.

    Aber:

      
    
    > SELECT                    -- Schlüsselwort SELECT gehört zu jedem ANSI-SQL-Standard  
    
          last_name             -- Spaltenname korrekt nach ANSI  
    
    > FROM                      -- Schlüsselwort FROM korrekt nach ANSI  
    
          employees  
    
    > WHERE                     -- Schlüsselwort WHERE korrekt nach ANSI  
    
          last_name LIKE 'J%'   -- Spaltenname in Ordnung  
                                -- Operator LIKE korrekt nach ANSI  
                                -- Wildcard-Zeichen % sollte auch ANSI entsprechen  
    
    > OR                        -- Operator OR sollte auch korrekt sein  
    
          last_name LIKE 'K%'  
    
    > OR  
    
          last_name LIKE 'L%'  
    
    > OR  
    
          last_name LIKE 'M%'  
    
    

    Was zum Geier soll hier der ANSI-SQL-Spezifikation nicht entsprechen? Frag' das Deinen Dozenten, Betreuer. Ich bin der gleichen Ansicht wie Ilja: es entspricht der Spezifikation.

    Vielleicht soll statt OR ein anderer Operator verwendet werden, MySQL unterstützt beispielsweise auch || als logisches ODER (ist || nicht in Oracle der Verknüpfungsoperator für Zeichenketten?). T-SQL hingegen nur OR und T-SQL brüstet sich durchaus damit, irgendwelche älteren ANSI-SQL-Standards zu erfüllen :-)

    Alle weiteren Versuche von Dir zeugen eher von Verzweiflung und naivem Umgang mit dem IN-Operator. Sie sind bereits auf den ersten Blick völlig falsch.

    Eine Idee hätte ich noch:
    Ersetze den OR-Operator in Deiner WHERE-Klausel durch eine UNION-Operation für vier getrennte Abfragen, die jeweils die Daten mit einem Anfangsbuchstaben zurückliefern. Wenn Deine Ausbilder das haben wollten, dann gehörten sie gesteinigt.

    Freundliche Grüße

    Vinzenz

    1. yo,

      ist || nicht in Oracle der Verknüpfungsoperator für Zeichenketten?

      genau, das ist er

      Ersetze den OR-Operator in Deiner WHERE-Klausel durch eine UNION-Operation für vier getrennte Abfragen, die jeweils die Daten mit einem Anfangsbuchstaben zurückliefern.

      UNION ALL würde ich in diesem falle wieder vorziehen....

      Ilja

      1. Hallo!

        Er meint, mit einem „in“ würde es leichter gehen. Aber da erhalte ich auch nur Fehlermeldungen und keine Ergebnisse.

        Liebe Grüße,
        Markus

        1. Hallo Markus,

          Er meint, mit einem „in“ würde es leichter gehen. Aber da erhalte ich auch nur Fehlermeldungen und keine Ergebnisse.

          Wie bereits geschrieben, Deine Versuche zeugen von Verzweiflung - sie sind für jemand, der etwas Erfahrung hat, offensichtlich falsch und brauchen nicht näher diskutiert zu werden.

          IN vergleicht einen Wert mit einer Wertliste oder der Wertemenge einer einspaltigen Unterabfrage.

          In der Unterabfrage die gleiche OR-Verknüpfung zu machen, vereinfacht die Lösung nicht. Bleibt also die Wertliste. Du kannst dort keine Wildcards verwenden, wie Du in Deinem ersten Versuch bereits gemerkt hast.

          Somit bleibt übrig, eine Operation auf Deine Suchspalte anzuwenden, die Dir den ersten Buchstaben zurückliefert. Beispiele dafür wären ein CAST oder eine Funktion, die Dir eine Teilzeichenkette zurückliefert. Bei beidem weiß ich nicht, wie es mit der ANSI-SQL-Kompatibilität aussieht.

          T-SQL (MS SQL-Server) unterstützt beispielsweise folgendes:

            
          SELECT  
              last_name  
          FROM  
              employees  
          WHERE  
              -- Prokrustes: Passe den Wert der Spalte last_name in ein einziges Zeichen ein.  
              -- Alles, was über das Bett (das einzige Zeichen) hinausragt, wird abgeschnitten.  
              CAST(last_name AS VARCHAR(1)) IN ('J', 'K', 'L', 'M')  
          
          

          oder

            
          SELECT  
              last_name  
          FROM  
              employees  
          WHERE  
              -- Verwende die Funktion SUBSTRING (keine Ahnung, ob die in Oracle genauso  
              -- heißt und die gleichen Parameter entegennimmt), um das erste Zeichen zu  
              -- bekommen, das in last_name steht.  
              SUBSTRING(last_name, 1, 1) IN ('J', 'K', 'L', 'M')  
          
          

          Wie bereits erwähnt: Keine Garantie für ANSI-SQL-Kompatibilität oder Portierbarkeit.

          Zuguterletzt gäbe es auch noch die Möglichkeit des Vergleiches mit größer gleich J und echt kleiner N (wobei Groß-/Kleinschreibung ggf. berücksichtigt) werden muss.

          Freundliche Grüße

          Vinzenz

          1. Hi,

            Wohl quasi jedes aktuell erhältliche Datenbanksystem, inkl. diesem ominösen MS Access, besitzt eingebaute Zeichenketten-Funktionen.

            LEFT(last_name,1) sollte auch erfolgreich sein. ;)  Sowohl LEFT als auch SUBSTRING sind nach diversen Seiten im Netz ANSI-SQL.

            Hier zeigt sich wieder mal (wie in den anderen Beiträgen) die Unwilligkeit des Ausgangsbeitragsschreibers, mal einfach die verdammte Dokumentation von Oracle zu bemühen (auf welche ich u.a. schon mind. 1x verlinkt habe) oder einfach mal bei google nach "ansi sql string function" zu suchen.

            Ciao, Frank

          2. yo,

            Somit bleibt übrig, eine Operation auf Deine Suchspalte anzuwenden, die Dir den ersten Buchstaben zurückliefert. Beispiele dafür wären ein CAST oder eine Funktion, die Dir eine Teilzeichenkette zurückliefert. Bei beidem weiß ich nicht, wie es mit der ANSI-SQL-Kompatibilität aussieht.

            ich würde bei LIKE und OR bleiben, bzw. bei LIKE und UNION ALL. Oracle kann zwar funktionale indexe, aber ich würde dafür nicht extra welche erstelluen wollen, wenn es eine andere Lösung gibt, die einen vorhanden Index schon benutzt.

            Ilja

      2. Hallo Ilja,

        ist || nicht in Oracle der Verknüpfungsoperator für Zeichenketten?
        genau, das ist er

        daraus schließe ich messerscharf, dass || in Oracle nicht der Operator für das logische ODER sein kann :-)

        Ersetze den OR-Operator in Deiner WHERE-Klausel durch eine UNION-Operation für vier getrennte Abfragen, die jeweils die Daten mit einem Anfangsbuchstaben zurückliefern.

        UNION ALL würde ich in diesem falle wieder vorziehen....

        Stimmt!

        <anmerkung modus="ausrede">Das herauszufinden hatte ich Markus als Übung überlassen.</anmerkung>

        Freundliche Grüße

        Vinzenz