sql >> Database >  >> RDS >> Sqlserver

SQL Server CASE-expressie

In SQL Server is de T-SQL CASE expressie is een scalaire expressie die een waarde retourneert op basis van voorwaardelijke logica. Het evalueert een lijst met voorwaarden en retourneert een waarde, gebaseerd op de uitkomst van die voorwaarden..

In sommige opzichten is de SQL Server CASE uitdrukking lijkt op IF...ELSE . Echter, CASE stelt u in staat om te controleren op meerdere voorwaarden, terwijl IF...ELSE niet.

In SQL Server, IF...ELSE is een trefwoord voor controle van de stroomtaal, terwijl CASE is niet. De CASE expressie kan niet worden gebruikt om de uitvoeringsstroom van T-SQL-instructies, instructieblokken, door de gebruiker gedefinieerde functies en opgeslagen procedures te regelen.

De 2 vormen van CASE-expressie

Er zijn twee vormen van CASE uitdrukking in SQL Server:

  • Eenvoudige CASE uitdrukking
  • Gezocht CASE uitdrukking

Deze worden hieronder toegelicht met voorbeelden.

Formulier 1 – De eenvoudige CASE-expressie

De eenvoudige CASE uitdrukking vergelijkt een uitdrukking met een reeks eenvoudige uitdrukkingen om het resultaat te bepalen.

Hier is een eenvoudig voorbeeld om te demonstreren hoe een CASE expressie werkt in SQL Server.

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
    CASE @stock_ticker  
        WHEN 'AAPL' THEN 'Apple'
        WHEN 'FB' THEN 'Facebook'
        WHEN 'V' THEN 'Visa'
        ELSE 'Not in the portfolio'  
    END

Resultaat:

+-----------+
| Company   |
|-----------|
| Visa      |
+-----------+

In dit voorbeeld is mijn CASE expressie maakt deel uit van een SELECT uitspraak. Het controleert op drie voorwaarden en heeft een ELSE om te voorzien in alles wat niet onder de drie voorwaarden valt.

In dit geval is de aandelenticker V komt overeen met de derde WHEN uitdrukking, en de uitdrukking geleverd door THEN wordt geretourneerd.

Voor alle duidelijkheid:de eigenlijke CASE uitdrukking is dit deel:

    CASE @stock_ticker  
        WHEN 'AAPL' THEN 'Apple'
        WHEN 'FB' THEN 'Facebook'
        WHEN 'MA' THEN 'Mastercard'
        WHEN 'V' THEN 'Visa'
        ELSE 'Not in the portfolio'  
    END

Wat CASE doet is, het controleert de waarde van elke WHEN expressie tegen de invoerexpressie. In mijn voorbeeld, de @stock_ticker variabele is de invoerexpressie. Daarom controleert het de waarde van elke WHEN uitdrukking tegen de @stock_ticker variabel.

Wanneer/als het een overeenkomst vindt, retourneert het de uitdrukking die wordt gegeven door THEN .

Mijn voorbeeld gebruikt drie WHEN uitdrukkingen, maar het had meer en minder kunnen zijn, afhankelijk van mijn vereisten.

Formulier 2 – De gezochte CASE-expressie

De gezochte CASE expression evalueert een set Booleaanse expressies om het resultaat te bepalen.

Hier is een voorbeeld van een gezochte CASE uitdrukking.

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        ELSE 'Expensive'  
    END

Resultaat:

+-----------------+
| Affordability   |
|-----------------|
| Expensive       |
+-----------------+

Een gezochte CASE expressie heeft geen invoerexpressie zoals de eenvoudige CASE uitdrukking.

U herinnert zich dat in onze eenvoudige CASE uitdrukking, het begon met CASE @stock_ticker , en daarom wisten we dat de WHEN uitdrukkingen evalueerden allemaal tegen de waarde van @stock_ticker .

Met de gezochte CASE expressie, bieden we aan het begin geen invoerexpressie op die manier. In plaats daarvan wordt elke WHEN expressie bevat een Booleaanse expressie waarvoor geëvalueerd moet worden.

Een databasevoorbeeld

Hier is een voorbeeld dat laat zien hoe de CASE expressie kan worden gebruikt binnen een databasequery.

USE WideWorldImporters;
SELECT 
    CityName AS [City], 
    LatestRecordedPopulation AS [Population], 
    Size =  
      CASE 
         WHEN LatestRecordedPopulation < 2000000 THEN 'Small City'  
         WHEN LatestRecordedPopulation >= 2000000 AND LatestRecordedPopulation < 3000000 THEN 'Big City' 
         ELSE 'Really Big City'
      END 
FROM Application.Cities
WHERE LatestRecordedPopulation > 1000000;

Resultaat:

+--------------+--------------+-----------------+
| City         | Population   | Size            |
|--------------+--------------+-----------------|
| Brooklyn     | 2565635      | Big City        |
| Chicago      | 2695598      | Big City        |
| Dallas       | 1197816      | Small City      |
| Houston      | 2099451      | Big City        |
| Los Angeles  | 3792621      | Really Big City |
| Manhattan    | 1619090      | Small City      |
| New York     | 8175133      | Really Big City |
| Philadelphia | 1526006      | Small City      |
| Phoenix      | 1445632      | Small City      |
| Queens       | 2272771      | Big City        |
| San Antonio  | 1327407      | Small City      |
| San Diego    | 1307402      | Small City      |
| The Bronx    | 1408473      | Small City      |
+--------------+--------------+-----------------+

Dit voorbeeld gebruikt een gezochte CASE expressie om de resultaten van de LatestRecordedPopulation . te evalueren kolom van de Application.Cities tafel.

Gegevenstypen

In SQL Server, het gegevenstype van de invoerexpressie en de WHEN uitdrukkingen moeten hetzelfde zijn of moeten een impliciete conversie zijn.

Dit is wat er gebeurt als ze dat niet zijn:

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
      CASE @stock_ticker  
         WHEN 1 THEN 'Apple'
         WHEN 2 THEN 'Facebook'
         WHEN 3 THEN 'Mastercard'
         WHEN 4 THEN 'Visa'
         ELSE 'Not in the portfolio'  
      END

Resultaat:

Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the varchar value 'V' to data type int.

Orde van evaluatie

De T-SQL CASE expressie evalueert zijn voorwaarden opeenvolgend en stopt met de eerste voorwaarde waarvan aan de voorwaarde is voldaan.

Laten we om dit te demonstreren meerdere WHEN . gebruiken uitdrukkingen die dezelfde waarde delen:

DECLARE @stock_ticker varchar(4) = 'V';

SELECT Company =  
    CASE @stock_ticker  
        WHEN 'V' THEN 'Visa 1'
        WHEN 'V' THEN 'Visa 2'
        WHEN 'V' THEN 'Visa 3'
        ELSE 'Not in the portfolio'  
    END

Resultaat:

+-----------+
| Company   |
|-----------|
| Visa 1    |
+-----------+

In dit geval stopte het bij de eerste WHEN uitdrukking.

Er kan zich een incidenteel scenario voordoen waarbij een uitdrukking wordt geëvalueerd vóór een CASE expressie ontvangt de resultaten van de expressie als invoer. In dergelijke scenario's kunt u een fout krijgen. Dit kan gebeuren als u een geaggregeerde expressie opneemt als de WHEN uitdrukking.

Om deze reden adviseert Microsoft dat:

U mag alleen afhankelijk zijn van de evaluatievolgorde van de WHEN-voorwaarden voor scalaire expressies (inclusief niet-gecorreleerde subquery's die scalaire waarden retourneren), niet voor geaggregeerde expressies.

ELSE is optioneel

De ELSE argument is optioneel. Daarom zouden we ons voorbeeld van "betaalbaarheid" als volgt kunnen herschrijven:

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 THEN 'Expensive'
    END    

Resultaat:

+-----------------+
| Affordability   |
|-----------------|
| Expensive       |
+-----------------+

Houd er echter rekening mee dat u kunt eindigen met NULL als u de ELSE . weglaat argument.

Het volgende voorbeeld resulteert in NULL :

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
    END    

Resultaat:

+-----------------+
| Affordability   |
|-----------------|
| NULL            |
+-----------------+

In dergelijke gevallen kunnen we altijd een ELSE . toevoegen argument, voor het geval dat (sorry voor de woordspeling!):

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
        ELSE 'Unknown'
    END  

Resultaat:

+-----------------+
| Affordability   |
|-----------------|
| Unknown         |
+-----------------+

Toegegeven, dit voorbeeld is waarschijnlijk een beetje gekunsteld. Het is tenslotte niet nodig om "duur" te begrenzen. Als iets duur is voor minder dan $ 1000, dan is het ook duur als het meer dan $ 1000 is.

Maar het punt is dat je ELSE . kunt gebruiken om iets te vangen dat niet onder de WHEN . valt uitdrukking/en.

Geneste CASE-expressies

U kunt CASE nesten uitdrukkingen indien nodig.

DECLARE @price int, @on_sale bit;
SET @price = 1500;
SET @on_sale = 1;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 THEN 
            CASE @on_sale
                WHEN 0 THEN 'Expensive (but it''s not currently on sale)' 
                WHEN 1 THEN 'Expensive (and it''s already on sale!)'
            END
    END

Resultaat:

+---------------------------------------+
| Affordability                         |
|---------------------------------------|
| Expensive (and it's already on sale!) |
+---------------------------------------+

Het is echter belangrijk op te merken dat er slechts 10 niveaus van nesting zijn toegestaan ​​voor CASE expressies in SQL Server. Als je meer dan 10 niveaus probeert te nesten, krijg je een foutmelding.

GEVAL in een ORDER BY-clausule

Zoals gezegd, de T-SQL CASE expressie kan worden gebruikt in elke instructie of clausule die een geldige expressie toestaat. Daarom kunt u het gebruiken in instructies zoals SELECT , UPDATE , DELETE en SET , en in clausules zoals IN , WHERE , ORDER BY , GROUP BY , en HAVING .

Een CASE gebruiken uitdrukking in de ORDER BY . van een instructie clausule kan handig zijn wanneer u een speciale uitzondering wilt maken voor bepaalde waarden bij het bestellen van uw resultaten.

Stel dat we de volgende query uitvoeren op een tabel met muziekgenres.

SELECT Genre 
FROM MusicGenres
ORDER BY Genre ASC;

Resultaat:

+---------+
| Genre   |
|---------|
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Metal   |
| Other   |
| Pop     |
| Rap     |
| Rock    |
+---------+

Hier rangschikken we de resultaten op Genre kolom, in oplopende volgorde.

Dit is prima, op één ding na. Het genre genaamd Overig . Zou het niet mooi zijn als we Overig . konden verplaatsen naar beneden?

We kunnen dit bereiken met de CASE expressie door de bovenstaande query te nemen en deze als volgt aan te passen.

SELECT Genre
FROM MusicGenres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC;

Resultaat:

+---------+
| Genre   |
|---------|
| Blues   |
| Country |
| Hip Hop |
| Jazz    |
| Metal   |
| Pop     |
| Rap     |
| Rock    |
| Other   |
+---------+

CASE in een UPDATE-instructie

Hier is een voorbeeld van het gebruik van een CASE uitdrukking in een UPDATE verklaring.

Stel dat we de volgende tabel hebben:

+---------+-----------+-----------+----------+
| DogId   | DogName   | GoodDog   | Dinner   |
|---------+-----------+-----------+----------|
| 1       | Fetch     | 1         | NULL     |
| 2       | Fluffy    | 0         | NULL     |
| 3       | Wag       | 0         | NULL     |
| 1001    | Brian     | 1         | NULL     |
| 1002    | Rambo     | 0         | NULL     |
| 1003    | BamBam    | 1         | NULL     |
+---------+-----------+-----------+----------+

We hebben onlangs het Dinner . toegevoegd kolom, en het is nog steeds NULL , wachtend op het invoegen van waarden.

Maar de in te voegen waarden zijn afhankelijk van de waarde van de GoodDog kolom.

We zouden een CASE kunnen gebruiken uitdrukking in een dergelijk scenario.

UPDATE Dogs 
SET Dinner = 
    CASE GoodDog
        WHEN 1 THEN 'Sunday Roast'
        ELSE 'Airline food'
    END

SELECT * FROM Dogs;

Resultaat:

+---------+-----------+-----------+--------------+
| DogId   | DogName   | GoodDog   | Dinner       |
|---------+-----------+-----------+--------------|
| 1       | Fetch     | 1         | Sunday Roast |
| 2       | Fluffy    | 0         | Airline food |
| 3       | Wag       | 0         | Airline food |
| 1001    | Brian     | 1         | Sunday Roast |
| 1002    | Rambo     | 0         | Airline food |
| 1003    | BamBam    | 1         | Sunday Roast |
+---------+-----------+-----------+--------------+

CASE in een INSERT-instructie

We kunnen de tabel uit het bovenstaande voorbeeld nemen en een nieuwe waarde invoegen.

En we kunnen weer profiteren van de CASE expressie om de juiste waarde in te voegen in het Dinner kolom.

DECLARE @DogName nvarchar(60), @GoodDog bit;
SET @DogName = 'Lazy';
SET @GoodDog = 0;

INSERT INTO Dogs ( DogName, GoodDog, Dinner )
VALUES (
    @DogName,
    @GoodDog,
    CASE @GoodDog
        WHEN 1 THEN 'Sunday Roast'
        ELSE 'Airline food'
    END
    );

SELECT * FROM Dogs;

Resultaat:

+---------+-----------+-----------+--------------+
| DogId   | DogName   | GoodDog   | Dinner       |
|---------+-----------+-----------+--------------|
| 1       | Fetch     | 1         | Sunday Roast |
| 2       | Fluffy    | 0         | Airline food |
| 3       | Wag       | 0         | Airline food |
| 1001    | Brian     | 1         | Sunday Roast |
| 1002    | Rambo     | 0         | Airline food |
| 1003    | BamBam    | 1         | Sunday Roast |
| 1004    | Lazy      | 0         | Airline food |
+---------+-----------+-----------+--------------+

Deze keer de CASE expressie evalueerde de waarde van een variabele die we zojuist hadden ingesteld en voegde vervolgens de juiste waarde toe aan het Dinner kolom.

Is het een CASE-statement of CASE-expressie?

In SQL worden veel dingen een "statement" genoemd, terwijl ze in feite iets anders zijn. Dit lijkt ook te gelden voor de T-SQL “CASE verklaring”.

Hoewel er vaak naar wordt verwezen als de CASE statement, is het nauwkeuriger om het de CASE . te noemen uitdrukking . Dit is ook hoe de Microsoft-documentatie ernaar verwijst.

In SQL Server is CASE . geen instructie zelf, maar kan worden gebruikt in elke instructie of clausule die een geldige expressie toestaat. Een uitdrukking is een combinatie van symbolen en operatoren die worden geëvalueerd om een ​​enkele gegevenswaarde te verkrijgen.

Sommige DBMS'en maken echter onderscheid tussen de CASE statement, en de CASE expressie, en hebben voor elk een iets andere syntaxis. MySQL maakt onderscheid tussen de CASE statement en de CASE operator, die in wezen hetzelfde is als de CASE uitdrukking.


  1. Hoe MySQL op CentOS te upgraden

  2. Opties voor cloudback-up voor MySQL- en MariaDB-databases

  3. Hoe geef ik elke geregistreerde gebruiker zijn eigen url met behulp van PHP?

  4. pgAdmin-alternatieven - GUI ClusterControl voor PostgreSQL-databasebeheer