NOT i forespørgsel

Vi har endnu en logisk operator i SQL Server. Du har faktisk allerede mødt NOT et par gange. Se evt. lektionen om NULL, hvor NOT bliver brugt. I kombination med andre logiske operatorer, som AND og OR, er NOT i stand til at forfine dine betingelser i SQL-forespørgslerne.

Den logiske operator NOT

Denne operator vender resultatet af et udsagn fra SAND til FALSK eller omvendt. Eksempler:

1=2 – er FALSK
NOT 1=2 – er SAND
1<>2 – er SAND
NOT 1<>2 – er FALSK

NOT-operatoren bruges på denne måde i SQL:

SELECT Navn, Bynavn FROM Kunde
WHERE NOT Bynavn = 'Viborg'

Husk dog i forbindelse med NULL, skrives NOT efter IS:

SELECT Navn, Email FROM Kunde
WHERE Email IS NOT NULL

Dette er faktisk også gyldigt og giver samme resultat:

SELECT Navn, Email FROM Kunde
WHERE NOT Email IS NULL

Du kan også udføre NOT på et udtryk, som allerede indeholder NOT, altså dobbelt negation:

SELECT Navn, Email FROM Kunde
WHERE NOT Email IS NOT NULL

Eller, hvis du har lyst til at gå amok i dobbeltnegation:

SELECT Navn, Bynavn FROM Kunde
WHERE NOT NOT Bynavn = 'Viborg'

Brug af NOT med AND og OR

Tingene kan blive lidt mere komplicerede, når vi blander NOT ind i andre betingelser med AND eller OR. Lad os finde varer, der hedder noget med Boble og som ikke koster mellem 1 og 2 kr.

Første forsøg er forkert, da NOT kun påvirker første betingelse:

SELECT * FROM Vare
WHERE
    Varebetegnelse LIKE 'Boble%'
    AND
    NOT Pris > 1 AND Pris < 2

I stedet skal vi indkapsle prisbetingelsen i parentes, hvorved NOT påvirker hele udtrykket:

SELECT * FROM Vare
WHERE
    Varebetegnelse LIKE 'Boble%'
    AND
    NOT (Pris > 1 AND Pris < 2)

Prøv selv

  • Find kunder ikke i Nyborg
  • Find kunder i Nyborg med gyldig email
  • Find papkasser, hvor prisen ikke er mellem 4 og 6 kr.

NULL betyder tom

Der går som regel ikke lang tid med databaser, inden du støder på begrebet NULL. Denne lektion forklarer de vigtigste facetter af NULL i en database. Du får brug for dette senere og – vil jeg påstå – resten af din karriere med SQL Server, uanset om det er Microsoft SQL Server som i dette kursus, eller en af mange andre varianter af SQL-databaser. Som en lille bonus får du at se, hvordan du kan bruge SELECT uden at vælge en tabel, du bliver introduceret til beregninger i en SQL-forespørgsel.

Der er nogen ting man skal indse og acceptere, når man har med NULL at gøre i sine SQL forespørgsler. Først og fremmest: NULL er ikke en værdi! NULL betyder faktisk lige præcis, at feltet ikke har nogen værdi.

Lær dette udsagn:

NULL viser, at et felt ikke har en værdi.

Dette har nogle konsekvenser for sammenligning af værdier i en forespørgsel i SQL. Her er nogle udsagn, der alle gælder i SQL:

  • NULL er ikke det samme som nul: 0
  • NULL er ikke det samme som tom tekst: ”
  • NULL er ikke større end nul, tom tekst eller nogen som helst dato
  • NULL er ikke mindre end nul eller tom tekst eller nogen som helst dato
  • NULL er ikke større end, mindre end eller lig med NULL
  • Et felt har ikke værdien NULL
  • Et felt kan være NULL eller være ikke-NULL
  • Et felt med en værdi er altid ikke-NULL
  • NULL kan opstå, hvis et felt ikke tildeles en værdi
  • NULL kan forbydes i et felt i tabeldesign
  • NULL kan opstå, når man sammenkæder tabeller (se lektionen om left og right join), også for felter, der ikke må være NULL
  • Regnestykker med NULL er NULL:
    • 2+3=5, men 2+NULL er NULL
    • ‘Hans ‘ + ‘og Grethe’ = ‘Hans og Grethe’, men ‘Hans ‘ + NULL + ‘og Grethe’ er NULL
    • Du kan dividere med NULL, resultatet er NULL

Afgør, om et felt er tomt med IS NULL

I SQL-sproget og dermed i dine forespørgsler, kan du ikke sammenligne direkte med NULL. Følgende er simpelthen dybt ulovligt og vil aldrig give et resultat.

SELECT * FROM Kunde
WHERE Adresse2 = NULL

Bemærk, at du ikke får en fejl fra SQL Server. Det er faktisk tilladt at sammenligne med NULL, men der kommer bare aldrig et resultat.

Intet er lig med NULL

Du skal altid spørge, om værdien er NULL (på engelsk IS NULL):

SELECT * FROM Kunde
WHERE Adresse2 IS NULL

Eller du skal spørge, om værdien er ikke-NULL (på engelsk IS NOT NULL)

SELECT * FROM Kunde
WHERE Adresse2 IS NOT NULL

Du kan ikke regne med NULL

Jeg ved godt, overskriften lyder lidt som en onkelvittighed, men der er nu noget sandt i det. Hver gang NULL indgår i en beregning er resultatet altid NULL. Det er på én gang både befriende enkelt og frustrerende besværligt. Du kommer sikkert ud for, at du faktisk er mest interesseret i, at tomme felter opfører sig, som om de ikke er der, i stedet for at dominere resultatet. Der er en indbygget funktion til det formål, den hedder COALESCE og bruges lidt senere i denne lektion. Andre muligheder er at se lektionen om CASE, hvor du både har mulighed for at vælge, hvad NULL skal betyde i din aktuelle forespørgsel samt, hvad andre værdier skal kategorisere som.

Se denne forespørgsel. Bemærk udtrykket, Adresse1 + ' ' + Adresse2, der simpelthen tager Adresse1 lægger et mellemrum (omkranset af apostrofer) og Adresse2 til. Dermed sammensætter du en kolonne med værdier fra andre kolonner.

SELECT
    Navn,
    Adresse1 + ' ' + Adresse2,
    Bynavn
FROM Kunde

Løsningen ser umiddelbart fin ud, men resultatet er lidt nedslående. Problemet er, at Adresse2 i flere tilfælde er tom og derfor bliver resultatet i disse rækker NULL. Som det ses her:

For fuldstændighedens skyld i denne lektion, og så du ikke efterlades uden løsning på problematikken ovenfor, giver jeg et lille kig på en indbygget tekst-funktion (se mere i den lektionen om tekst-funktioner), der løser denne opgave. Med denne forespørgsel, hvor du anvender den indbyggede funktion CONCAT, kan du lægge tekster sammen uden at blive forstyrret af tomme felter. NULL-værdier ignoreres i dette tilfælde:

SELECT
    Navn,
    CONCAT(Adresse1, ' ', Adresse2),
    Bynavn
FROM Kunde
Resultatet er ret godt, men der er i flere tilfælde et usynligt mellemrum til sidst

Det er ikke kun skidt, at beregninger med NULL altid giver NULL. Denne forespørgsel viser alle rækker, hvor Email, Telefon eller begge er NULL i Kunde-tabellen på en ret nem måde uden at skrive flere betingelser med brug af OR (se lektionen om de logiske operatorer AND og OR):

SELECT Navn, Telefon, Email
FROM Kunde
WHERE Email + Telefon IS NULL

Håndter NULL med COALESCE-funktionen

Eksemplet ovenfor med håndteringen af NULL i Adresse2-feltet kan også håndteres med den indbyggede funktion COALESCE. Denne funktion returnerer første ikke-NULL værdi fra en liste af værdier. Her er der to muligheder. Enten vises værdien fra kolonnen Adresse2, eller hvis den er NULL, vises næste værdi, som er (Tomt felt).

SELECT
    Navn,
    Adresse2,
    COALESCE(Adresse2, '(Tomt felt)')
FROM Kunde

Jeg vender tilbage til sammenkædningen af adresser igen. Eksemplet med CONCAT ovenfor har den ulempe, at der tilføjes et mellemrum til sidst, hvis Adresse2 er NULL. Det er ikke altid ønskeligt. Der findes funktioner til at håndtere dette efterfølgende. Vi kan med COALESCE også håndtere dette ganske elegant. Denne forespørgsel lægger adresserne sammen (du kan bruge CONCAT, hvis du vil). COALESCE returnerer nu enten mellemrum + Adresse2 eller tom tekst (to apostroffer uden noget i mellem er en tom tekst).

SELECT
    Navn,
    Adresse1 + COALESCE(' ' + Adresse2, ''),
    Bynavn
FROM Kunde

Eksempler på beregninger med NULL

Du har tidligere i kapitlet om Simpel SELECT set, at kommandoen altid efterfølges af FROM og navnet på en tabel – jeg beklager påstanden. Det er løgn! Du kan sagtens bruge SELECT alene til at lave beregninger direkte i Management Studio.

SELECT NULL

Resultat: NULL

SELECT 2 + 3

Resultat: 5

SELECT 2 + 3 + NULL

Resultat: NULL

SELECT 30 / 5

Resultat: 6

SELECT 30 / NULL

Resultat: NULL

SELECT 30 / 0

Resultat: Fejl division med nul (Divide by zero error encountered).

Prøv selv

  • Find alle kunder, hvor Email er tom
  • Find alle kunder, hvor Email er udfyldt
  • Find alle kunder, hvor Email og Telefon er udfyldt
  • Find rækker i Kundeemner-tabellen, hvor telefon er tom tekst eller uden værdi