MySQL Vergelijkingsoperatoren
Home

MySQL Vergelijkingsoperatoren

MySQL Vergelijkingsoperatoren

De vergelijkingsoperatoren zijn de zelfde als die van veel andere programmeertalen.

Probleem

Bij het selecteren van rijen uit een tabel moet je de mogelijkheid hebben om waarden te kunnen vergelijken: zijn ze groter of kleiner dan, of groter of gelijk aan of kleiner of gelijk aan?

Oplossing

Symbool

Beschrijving

=

Gelijk

<

Kleiner dan

>

Groter dan

<=

Kleiner dan of gelijk aan

>=

Groter dan of gelijk aan

<> of !=

Verschillend

Enkele voorbeelden kunnen het gebruik van de vergelijksoperatoren verduidelijken.

USE ModernWays;
SELECT Familienaam, Titel FROM Boeken WHERE Familienaam < 'B';

Dit SELECT statement retourneert alle rijen uit de tabel Boeken waarvan de Familienaam kolom een waarde heeft die "kleiner" is dan 'B'. Wanneer is een string "kleiner" dan een andere string? Om op die vraag te antwoorden moet je eerst weten dat de namen in een bepaalde, normaal alfabetische volgorde (in het Engels collation order) worden gerangschikt. "Alle namen kleiner dan 'B'"" wil dan zeggen "alle namen die na het sorteren voor 'B' komen." De collation is dus een stel regels voor het vergelijken van tekens in een tekenset.

Als de familienaam Beth in je tabel voorkomt, wordt deze niet in de selectie opgenomen. Om ook die rij te selecteren, zou je kunnen denken om de expressie Familienaam <= 'B' te gebruiken:

use ModernWays;
select Familienaam, Titel from Boeken where Familienaam <= 'B';

Dit zal niet werken. Dat komt omdat we de boeken opvragen waarvan de familienaam van de auteur kleiner of gelijk is aan 'B'. De tekst 'Beth' is niet gelijk aan 'B' en is zeker niet kleiner! In het algemeen mag je dit onthouden: als een string A een prefix is van een string B, d.w.z. als string B letterlijk begint met de inhoud van A en dan nog meer tekst bevat, dan zal A altijd voor B gesorteerd worden. Zo wordt 'schoen' gesorteerd voor 'schoenmaker', omdat 'schoen' een prefix is van 'schoenmaker'. Maar er wordt éérst naar de letters gekeken en dan pas naar de lengte van de tekst. Zo wordt 'schoeisel' voor 'schoen' gesorteerd, omdat 'i' voor 'n' komt.

Als we 'B' als familienaam toevoegen, wordt die natuurlijk wel geselecteerd:

insert into Boeken (
   Familienaam,
   Titel,
   Voornaam)
values (
   'B',
   'Het Boek',
   'Jef');

select Titel, Familienaam from Boeken
   where Familienaam <= 'B';

Nu wordt 'B' wel getoond.

Stel dat je alle titels wilt van de auteurs wilt waarvan de familienaam begint met een' A' of een 'B'. Dan moet je de WHERE clausule verfijnen. Je zou dit kunnen proberen:

use ModernWays;
select Familienaam, Titel from Boeken where Familienaam <= 'Bz';
Maar hier zijn verschillende problemen mee. Als 'Bz' een prefix is van de naam van een auteur (niet erg waarschijnlijk, maar het zou kunnen), zal dit niet werken. Nog lastiger: dit is erg afhankelijk van de collation. Het is niet in elke collation zo dat 'Bz' voor 'Bé' komt, bijvoorbeeld. Sommige collations sorteren eerst de gebruikelijke 26 letters van het alfabet en pas daarna de letters met accenten.

Dit is beter:

select Familienaam, Titel from Boeken where Familienaam < 'C'

Hoe weet je wat er met accenten en hoofdletters gebeurt? Dat hangt ervan af of de gebruikte collation hoofdlettergevoelig (case sensitive) en/of accentgevoelig (accent sensitive) is.

Probeer dit eens uit (hoeft niet in een script):

insert into Boeken (
   Voornaam,
   Familienaam,
   Titel,
   Stad,
   Uitgeverij,
   Verschijningsdatum,
   Herdruk,
   Commentaar,
   Categorie
)
values
(
   'Emile',
   'Bréhier',
   'Cours de Philosophie',
   'Paris',
   'Gallimard',
   '1935',
   '1960',
   'Goed boek',
   'Filosofie'
),
(
   'Andre',
   'Breton',
   'Nadja',
   'Paris',
   'NRF',
   '1928',
   '?',
   'Nog te lezen',
   'Roman'
);

select Voornaam, Familienaam, Titel from Boeken
   where Familienaam <= 'Bret';

Als de collation voor Familienaam accentgevoelig is, zal je alleen het boek van Breton zien. Anders zal je ook dat van Bréhier zien. Als je onder MySQL de collation van de kolommen van de tabel Boeken te weten wil komen, gebruik je volgende query:

SHOW FULL COLUMNS FROM Boeken;

Er zijn véél collations, maar onthoud vooral volgende vuistregels:

Oefening

Veronderstel dat de collation SQL_Latin1_General_CP1_CI_AS is. Voorspel wat volgende code zal doen, zonder uit te voeren:
insert into Boeken (
   Voornaam,
   Familienaam,
   Titel,
   Stad,
   Uitgeverij,
   Verschijningsdatum,
   InsertedBy)
values
  ('Céline', 'Claus', 'De verwondering', 'Antwerpen', 'Manteau', '1970'),
   ('Celine' ,'Raes', 'Jagen en gejaagd worden', 'Antwerpen', 'De Bezige Bij', '1954'),
   ('CELINE', 'Sarthe', 'Het zijn en het niets', 'Parijs', 'Gallimard', '1943');

select * from Boeken where voornaam = 'Celine';

Schrijf daarna een script 0038__SelectBoekenCeline.sql dat deze code bevat en controleer of je voorspelling klopt.

Je kan de collation van een kolom ook aanpassen. Dit is een wijziging aan de structuur van onze tabel, dus we gebruiken hiervoor ALTER, het sleutelwoord om dingen te wijzigen in de DDL.

alter table Boeken
   alter column Voornaam nvarchar(50)
   collate Latin1_General_100_CS_AI;

Celine en Céline worden nu geretourneerd bij dezelfde query.

Je kan ook de collation tijdelijk aanpassen voor één query. Dit hebben we al eens gedaan in het script 0028__BoekenSelect.sql.

Oefening

Schrijf een script dat alle auteurs selecteert waarvan de familienaam begint met 'B', maar niet met iets anders. Noem dit 0039__BoekenSelectB.sql

Om alle boeken die in 2000 en ervoor verschenen zijn te selecteren kan je het volgende statement gebruiken:

use ModernWays;
select Voornaam, Familienaam, Titel from boeken
   where Verschijningsdatum <= '2000';
Schrijf dit uit in het script 0040__BoekenSelect en probeer uit. Let op: het type van de verschijningsdatum is char(4), dus er is sowieso ruimte voorzien voor vier karakters, maar je mag er minder ingeven. Dat heeft gevolgen, zoals je ziet in volgende oefening:

Oefening

Voeg met een script 0041__BoekenInsert.sql volgende twee boeken toe, exact zoals gegeven (laat andere kolommen weg):
FamilienaamTitelVerschijningsdatum
?Beowulf0975
OvidiusMetamorfosen8
Vraag dan alle boeken op die verschenen zijn voor '0976' in 0042__BoekenSelect.sql. Probeer uit en vraag uitleg als het resultaat niet is wat je verwacht!

Opmerking over NULL

Om na te gaan of een expressie NULL is, gebruik je de IS NULL of de IS NOT NULL i.p.v. de vergelijkingsoperatoren. Vergelijkingsoperatoren retourneren UNKNOWN, een speciale waarde.

select * from Boeken where Stad is null;

Let erop hoe we alledaagse manier van spreken omzetten in logische expressies. "Boeken die verschenen zijn na 2000" wordt WHERE Verschijningsdatum > '2000'.

Schrijf drie scripts, 0043__BoekenSelect.sql, 0044__BoekenSelect.sql en 0045__BoekenSelect.sql. Het eerste selecteert alle boeken van auteurs waarvoor de voornaam NULL is. Het tweede doet dit op de foute manier, dus met = NULL. Het derde doet het omgekeerde op de foute manier, dus met != NULL.

Test deze scripts zelf ook uit!

JI & VN
2019-03-23 10:02:54