2017-05-21 4 views
2

Ich habe zwei Abfragen geschrieben, um Spaltenwerte abzurufen, die entweder nicht mit Vokalen beginnen oder nicht mit Vokalen enden.Sind diese zwei SQL Server-Abfragen identisch?

Abfrage 1:

SELECT DISTINCT CITY 
FROM STATION 
WHERE city NOT LIKE '[aeiou]%' 
    OR city NOT LIKE '%[aeiou]' 

Abfrage 2:

SELECT DISTINCT CITY 
FROM STATION 
WHERE city NOT LIKE '[aeiou]%[aeiou]' 

mir nach, sollten sie gleiche Abfrage sein, da sie Testfälle leicht und filtern gleiche Ergebnis übergeben. Sind diese zwei verschiedenen Abfragen in jedem Szenario?

Antwort

1

Beide Abfragen rufen Städte ab, die am Anfang oder Ende ihres Namens einen Nicht-Vokal haben. Sie sollten die gleiche Ergebnismenge zurückgeben. Zum Beispiel stimmt "Miami" mit beiden Abfragen überein.

Sie sind jedoch nicht die gleichen. Man wird den zugrunde liegenden Operator like zweimal ausführen, und den anderen einmal. In diesem Fall ist der Leistungsunterschied wahrscheinlich nicht bemerkbar, könnte aber unter anderen Umständen einen Unterschied machen.

Wenn Sie Städte möchten, haben Vokale nicht am Anfang und Ende ihres Namens, dann:

WHERE city not like '[aeiou]%' AND city not like '%[aeiou]' 

oder:

WHERE city LIKE '[^aeiou]%[^aeiou]' 

„Miami“ entspricht nicht diese Bedingungen , aber "Boston" tut es.

2

Nein, sie sind nicht gleich. Es kann durch die Anwendung von de Morgan Regel zu sehen:

von

a = like '[aeiou]%' 
b = like '%[aeiou]'. 

!a or !b = !(a and b), 

wo die Ereignisse a und b gegeben Darüber hinaus a and b entspricht das Ereignis like '[aeiou]%[aeiou]', die im Grunde eine Reihe Kreuzung der zwei Sätze mit allen Ereignissen a und b.

EDIT: Der vorherige Satz ist falsch, und es erzeugt falsche Ergebnisse genau für Ein-Element-Strings. Um den Satz a and b zu finden, betrachten

a = { x | first element in {a,e,i,o,u} } 
b = { x | last element in {a,e,i,o,u} } 

Daher

a AND b = { x | first AND last element in {a,e,i,o,u} } 

Jetzt, im Gegensatz dazu like '[aeiou]%[aeiou]' die Teilmenge von a AND b ist, das ein weiteres optionales Zeichen zwischen dem ersten und dem letzten Elemente hat.

Sorry für die Verwirrung.

+0

Ja, das dachte ich mir, aber wie @stephan Lechner es ausdrückte, war ich skeptisch, gibt es Testfälle, bei denen sich die Abfragen anders verhalten. –

+0

@Kajal_T: ok, völlig richtig, sie sind nicht identisch. Ich poste die theoretische Untermauerung (der Fehler war im letzten Schritt). – davidhigh

5

Nein, sie verhalten sich anders. Ich erwartete einige Unterschiede mit Städten wie "a", weil eine Zeichenfolge mit der Länge 1 nicht Muster [aeiou]%[aeiou] übereinstimmen wird, aber sowohl [aeiou]% als auch %[aeiou] übereinstimmen kann. Probieren Sie es aus, und tatsächlich gibt es Unterschiede.Man kann immer noch diskutieren, welche der beiden Abfragen interpretieren 'a' korrekt, aber zumindest beide Abfragen verhalten sich anders:

SELECT * 
    FROM (VALUES ('aasfa') 
      , ('basda') 
      , ('asdfb') 
      , ('a') 
     ) t1 (c) 
     where c not like '[aeiou]%[aeiou]'; 

Ergebnis:

c 
----- 
basda 
asdfb 
a 

Abfrage:

SELECT * 
    FROM (VALUES ('aasfa') 
      , ('basda') 
      , ('asdfb') 
      , ('a') 
     ) t1 (c) 
     where c not like '[aeiou]%' 
or c not like '%[aeiou]' 

Ergebnis:

c 
----- 
basda 
asdfb 
1

Nein. Sie sind nicht gleich. Hier ist Beispieleingabe: xyz, axyz, xyza, axyza, a.

Die erste Abfrage wird zurückgegeben: xyz, axyz, xyza. In diesem 'AND' sollte verwendet werden, um die gewünschte Ausgabe zu erhalten. Die folgende Abfrage gibt nur xyz zurück.

2. Abfrage wird zurück: xyz, axyz, xyza, a. Dies liegt daran, dass die Bedingung

NOT LIKE '[aeiou]%[aeiou]' 

bedeutet, dass es nicht beginnen UND mit einem Vokal enden sollte. Daher wird axyza nicht ausgewählt, während a, axyz und xyza ausgewählt werden, obwohl sie nicht hätten sein sollen.

Verwandte Themen