• SQL中的CASE WHEN语句:从基础到高级应用指南


    SQL中的CASE WHEN语句:从基础到高级应用指南

    准备工作 - 表1: products 示例数据:

    我们使用一个名为"Products"的表,包含以下列:ProductID、ProductName、CategoryID、UnitPrice、StockQuantity。

    -- 建表
    CREATE TABLE `products` (
      `productID` int(11) NOT NULL,
      `productName` varchar(255) DEFAULT NULL,
      `categoryID` int(11) DEFAULT NULL,
      `unitPrice` int(11) DEFAULT NULL,
      `stockQuantity` int(11) DEFAULT NULL,
      PRIMARY KEY (`productID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    -- 样例数据
    INSERT INTO `products` VALUES (1, 'Laptop', 1, 800, 50);
    INSERT INTO `products` VALUES (2, 'Smartphone', 1, 500, 100);
    INSERT INTO `products` VALUES (3, 'T-shirt', 2, 20, 200);
    INSERT INTO `products` VALUES (4, 'Jeans', 2, 40, 150);
    INSERT INTO `products` VALUES (5, 'Headphones', 1, 100, 75);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 示例展示
    productIDproductNamecategoryIDunitPricestockQuantity
    1Laptop180050
    2Smartphone1500100
    3T-shirt220200
    4Jeans240150
    5Headphones110075

    一. CASE WHEN 基础使用

    1. CASE WHEN-基本使用

    SELECT
    	ProductName,
    	UnitPrice,
    CASE
    		
    		WHEN UnitPrice > 100 THEN
    		'Expensive' ELSE 'Affordable' 
    	END AS PriceCategory 
    FROM
    	Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查询结果:

    ProductNameUnitPricePriceCategory
    Laptop800Expensive
    Smartphone500Expensive
    T-shirt20Affordable
    Jeans40Affordable
    Headphones100Affordable

    2. CASE WHEN-多条件

    SELECT
    	productName,
    	stockQuantity,
    CASE
    		
    		WHEN stockQuantity > 100 THEN
    		'In Stock' 
    		WHEN stockQuantity > 50 THEN
    		'Limited Stock' ELSE 'Out of Stock' 
    	END AS StockStatus 
    FROM
    	products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查询结果:

    productNamestockQuantityStockStatus
    Laptop50Out of Stock
    Smartphone100Limited Stock
    T-shirt200In Stock
    Jeans150In Stock
    Headphones75Limited Stock

    3. CASE WHEN-聚合函数

    SELECT
    	categoryID,
    	AVG( unitPrice ) AS AvgPrice,
    CASE
    		
    		WHEN AVG( unitPrice ) > 50 THEN
    		'High Price' ELSE 'Low Price' 
    	END AS PriceCategory 
    FROM
    	products 
    GROUP BY
    	categoryID;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 查询结果
    categoryIDAvgPricePriceCategory
    1466.6667Hign Price
    230low Price

    4. CASE WHEN-日期条件

    SELECT
    	productName,
    CASE
    		
    		WHEN EXTRACT( MONTH FROM CURRENT_DATE ) = 8 THEN
    		( SELECT NOW() ) ELSE 'Other Month' 
    	END AS CurrentTime 
    FROM
    	products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查询结果
    productNameCurrentTime
    Laptop2023/8/30 19:14
    Smartphone2023/8/30 19:14
    T-shirt2023/8/30 19:14
    Jeans2023/8/30 19:14
    Headphones2023/8/30 19:14

    5. CASE WHEN-用于排序

    SELECT
        ProductName,
        UnitPrice,
        CASE
            WHEN UnitPrice > 50 THEN 'Expensive'
            ELSE 'Affordable'
        END AS PriceCategory
    FROM Products
    ORDER BY UnitPrice DESC;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查询结果
    productNameunitPricePriceCategory
    Laptop1902/3/10 0:00Expensive
    Smartphone1901/5/14 0:00Expensive
    Headphones1900/4/9 0:00Expensive
    Jeans1900/2/9 0:00Affordable
    T-shirt1900/1/20 0:00Affordable

    6. CASE WHEN-子查询

    SELECT
    	productName,
    	unitPrice,
    	( CASE WHEN unitPrice > ( SELECT AVG( unitPrice ) FROM products ) THEN 'Above Avg' ELSE 'Below Avg' END ) AS PriceComparison 
    FROM
    	products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 查询结果
    productNameunitPricePriceComparison
    Laptop800Above Avg
    Smartphone500Above Avg
    T-shirt20Below Avg
    Jeans40Below Avg
    Headphones100Below Avg

    7. CASE WHEN-计算字段

    SELECT
        ProductName,
        UnitPrice,
        StockQuantity,
        CASE
            WHEN StockQuantity > 0 THEN UnitPrice / StockQuantity
            ELSE 0
        END AS PricePerUnit
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查询结果
    productNameunitPricestockQuantityPricePerUnit
    Laptop8005016
    Smartphone5001005
    T-shirt202000.1
    Jeans401500.2667
    Headphones100751.3333

    8. CASE WHEN-动态列名

    SELECT
    	productName,
    	unitPrice,
    	stockQuantity,
    CASE
    		
    		WHEN stockQuantity > 150 THEN
    		'High' 
    		WHEN stockQuantity > 100 THEN
    		'Medium' ELSE 'Low' 
    	END AS StockCategory,
    CASE
    		
    		WHEN stockQuantity > 100 THEN
    		stockQuantity * 1.1 ELSE stockQuantity * 1.05 
    	END AS AdjustedStock 
    FROM
    	products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 查询结果
    productNameunitPricestockQuantityStockCategoryAdjustedStock
    Laptop80050Low52.5
    Smartphone500100Low105
    T-shirt20200High220
    Jeans40150Medium165
    Headphones10075Low78.75

    9. CASE WHEN-带有嵌套逻辑

    SELECT
        ProductName,
        UnitPrice,
        CASE
            WHEN StockQuantity > 100 THEN
                CASE
                    WHEN UnitPrice > 50 THEN 'High Demand, High Price'
                    ELSE 'High Demand, Affordable'
                END
            ELSE 'Low Demand'
        END AS ProductStatus
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 查询结果
    productNameunitPriceProductStatus
    Laptop800Low Demand
    Smartphone500Low Demand
    T-shirt20High Demand, Affordable
    Jeans40High Demand, Affordable
    Headphones100Low Demand

    10. CASE WHEN-处理字符串匹配

    SELECT
        ProductName,
        CASE
            WHEN ProductName LIKE '%Laptop%' THEN 'Electronics'
            WHEN ProductName LIKE '%T-shirt%' THEN 'Clothing'
            ELSE 'Other'
        END AS Category
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 查询结果
    productNameCategory
    LaptopElectronics
    SmartphoneOther
    T-shirtClothing
    JeansOther
    HeadphonesOther

    11. CASE WHEN-用于条件合并

    SELECT
        ProductName,
        UnitPrice,
        CASE
            WHEN UnitPrice > 50 AND StockQuantity > 50 THEN 'High Price, High Stock'
            WHEN UnitPrice > 50 OR StockQuantity > 50 THEN 'High Price or High Stock'
            ELSE 'Low Price and Low Stock'
        END AS ProductStatus
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查询结果
    productNameunitPriceProductStatus
    Laptop800High Price or High Stock
    Smartphone500High Price, High Stock
    T-shirt20High Price or High Stock
    Jeans40High Price or High Stock
    Headphones100High Price, High Stock

    12. CASE WHEN-处理多列

    SELECT
        ProductName,
        UnitPrice,
        StockQuantity,
        CASE
            WHEN StockQuantity > 50 AND UnitPrice <
    
     30 THEN 'Popular and Affordable'
            WHEN StockQuantity <= 50 AND UnitPrice < 30 THEN 'Limited Stock, Affordable'
            WHEN StockQuantity > 50 AND UnitPrice >= 30 THEN 'Popular and Expensive'
            ELSE 'Limited Stock, Expensive'
        END AS ProductCategory
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 查询结果
    productNameunitPricestockQuantityProductCategory
    Laptop80050Limited Stock, Expensive
    Smartphone500100Popular and Expensive
    T-shirt20200Popular and Affordable
    Jeans40150Popular and Expensive
    Headphones10075Popular and Expensive

    13. CASE WHEN-加入窗口函数

    SELECT
        ProductName,
        UnitPrice,
        StockQuantity,
        CASE
            WHEN StockQuantity > AVG(StockQuantity) OVER () THEN 'Above Avg Stock'
            ELSE 'Below Avg Stock'
        END AS StockComparison
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 查询结果
    productNameunitPricestockQuantityStockComparison
    T-shirt20200Above Avg Stock
    Laptop80050Below Avg Stock
    Jeans40150Above Avg Stock
    Smartphone500100Below Avg Stock
    Headphones10075Below Avg Stock

    二. CASE WHEN 进阶使用

    1. 基于历史数据的趋势预测

    样例SQL:

    SELECT
        p.ProductID,
        p.ProductName,
        s.SaleDate,
        s.QuantitySold,
        CASE
            WHEN s.QuantitySold > LAG(s.QuantitySold) OVER (PARTITION BY p.ProductID ORDER BY s.SaleDate) THEN 'Increased'
            WHEN s.QuantitySold < LAG(s.QuantitySold) OVER (PARTITION BY p.ProductID ORDER BY s.SaleDate) THEN 'Decreased'
            ELSE 'Stable'
        END AS Trend
    FROM Products p
    JOIN SalesHistory s ON p.ProductID = s.ProductID;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2. 基于不同维度的复杂分析

    样例SQL:

    SELECT
        o.OrderID,
        o.OrderDate,
        SUM(CASE WHEN p.CategoryID = 1 THEN o.Quantity ELSE 0 END) AS ElectronicsQuantity,
        SUM(CASE WHEN p.CategoryID = 2 THEN o.Quantity ELSE 0 END) AS ClothingQuantity,
        SUM(CASE WHEN p.CategoryID = 3 THEN o.Quantity ELSE 0 END) AS OtherQuantity
    FROM Orders o
    JOIN Products p ON o.ProductID = p.ProductID
    GROUP BY o.OrderID, o.OrderDate;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3. 多层次CASE WHEN分析

    样例SQL:

    SELECT
        EmployeeID,
        FirstName,
        LastName,
        Salary,
        CASE
            WHEN Salary > 70000 THEN 'High'
            WHEN Salary > 60000 THEN 'Medium'
            WHEN Salary > 50000 THEN 'Low'
            ELSE 'Very Low'
        END AS SalaryLevel,
        CASE
            WHEN Salary > 60000 THEN 'Above Average'
            ELSE 'Below Average'
        END AS SalaryComparison
    FROM Employees;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. 使用CASE WHEN进行数据分桶

    样例SQL:

    SELECT
        CustomerID,
        Age,
        Gender,
        CASE
            WHEN Age < 30 THEN 'Young'
            WHEN Age >= 30 AND Age < 40 THEN 'Middle-aged'
            ELSE 'Senior'
        END AS AgeGroup,
        CASE
            WHEN Gender = 'Male' THEN 'Male'
            WHEN Gender = 'Female' THEN 'Female'
            ELSE 'Other'
        END AS GenderCategory
    FROM Customers;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    5. 基于多条件的复杂逻辑判断

    样例SQL:

    SELECT
        OrderID,
        OrderDate,
        SUM(CASE WHEN Quantity * Price > 500 THEN Quantity ELSE 0 END) AS HighValueItems,
        SUM(CASE WHEN Quantity * Price > 100 AND Quantity * Price <= 500 THEN Quantity ELSE 0 END) AS MediumValueItems,
        SUM(CASE WHEN Quantity * Price <= 100 THEN Quantity ELSE 0 END) AS LowValueItems
    FROM Orders
    GROUP BY OrderID, OrderDate;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    三. CASE WHEN 业务场景常用技巧

    1. 数据重编码

    您可以使用CASE WHEN来对现有数据进行重新编码,例如将文本值转换为数字编码或将某些字符串转换为更易于处理的标识符。

    SELECT
        customerName,
        CASE
            WHEN customerType = 'Individual' THEN 1
            WHEN customerType = 'Corporate' THEN 2
            ELSE 0
        END AS CustomerTypeCode
    FROM Customers;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2. 条件分组

    使用CASE WHEN可以在查询结果中创建不同的数据分组,而无需在实际数据中创建新的列。

    SELECT
        productName,
        SUM(quantity) AS totalQuantity,
        CASE
            WHEN SUM(quantity) > 100 THEN 'High'
            WHEN SUM(quantity) > 50 THEN 'Medium'
            ELSE 'Low'
        END AS QuantityGroup
    FROM Sales
    GROUP BY productName;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3. 动态排序规则

    通过在ORDER BY子句中使用CASE WHEN,您可以根据不同条件动态调整查询结果的排序规则。

    SELECT
        productName,
        unitPrice
    FROM Products
    ORDER BY
        CASE
            WHEN category = 'Electronics' THEN unitPrice
            WHEN category = 'Clothing' THEN unitPrice * 0.9
            ELSE unitPrice * 1.1
        END;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4. 分位数分析

    使用CASE WHEN可以在查询结果中对数据进行分位数分析,识别哪些数据点位于不同的分位数区间。

    SELECT
        productName,
        unitPrice,
        CASE
            WHEN unitPrice <= PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY unitPrice) THEN 'Q1'
            WHEN unitPrice <= PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY unitPrice) THEN 'Q2'
            WHEN unitPrice <= PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY unitPrice) THEN 'Q3'
            ELSE 'Q4'
        END AS PriceQuartile
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5. 缺失数据填充

    使用CASE WHEN可以根据条件将缺失的数据点填充为特定值,从而更好地处理数据缺失情况。

    SELECT
        orderID,
        orderDate,
        CASE
            WHEN orderAmount IS NULL THEN 0
            ELSE orderAmount
        END AS FilledOrderAmount
    FROM Orders;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    6. 日期区间分析

    使用CASE WHEN可以对日期进行区间分析,例如判断每个日期属于哪个季节、哪个月份等。

    SELECT
        orderDate,
        CASE
            WHEN EXTRACT(MONTH FROM orderDate) IN (12, 1, 2) THEN 'Winter'
            WHEN EXTRACT(MONTH FROM orderDate) IN (3, 4, 5) THEN 'Spring'
            WHEN EXTRACT(MONTH FROM orderDate) IN (6, 7, 8) THEN 'Summer'
            ELSE 'Fall'
        END AS Season
    FROM Orders;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    7. 业务阶段分析

    使用CASE WHEN可以根据特定业务规则判断数据所处的不同阶段,如用户生命周期阶段、订单处理阶段等。

    SELECT
        userID,
        registrationDate,
        CASE
            WHEN NOW() - registrationDate < INTERVAL '30 days' THEN 'New User'
            WHEN NOW() - registrationDate < INTERVAL '90 days' THEN 'Regular User'
            ELSE 'Inactive User'
        END AS UserStage
    FROM Users;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    8. 动态列选择

    使用CASE WHEN可以在查询结果中根据条件选择不同的列,从而根据业务需求定制查询结果。

    SELECT
        orderID,
        orderDate,
        CASE
            WHEN displayPrice = 'Gross' THEN grossPrice
            ELSE netPrice
        END AS SelectedPrice
    FROM Orders;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    9. 异常值标记

    使用CASE WHEN可以根据条件识别和标记异常数据点,帮助进行数据质量分析。

    SELECT
        customerID,
        orderDate,
        orderAmount,
        CASE
            WHEN orderAmount < 0 THEN 'Negative'
            WHEN orderAmount > 10000 THEN 'High Amount'
            ELSE 'Normal'
        END AS DataQuality
    FROM Orders;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    10. 数据格式转换

    使用CASE WHEN可以在不同的数据格式之间进行转换,例如将布尔值转换为文本标签。

    SELECT
        productID,
        productName,
        inStock,
        CASE
            WHEN inStock THEN 'Available'
            ELSE 'Out of Stock'
        END AS StockStatus
    FROM Products;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    CSP-J 2023 入门级 第一轮 完善程序(2)
    在pycharm中配置nodejs
    65.Undertow代替Tomcat
    基于Rook+Ceph的云原生存储架构剖析
    软件测试技术之如何编写测试用例(5)
    three-tile: 三维瓦片地图框架应用示例源码-GitHub
    分布式锁实现对比
    懒人福利:6款Sketch插件合集,提升设计效率爆款推荐!
    Compose中Canvas绘制
    对话MySQL之父:一个优秀程序员可抵5个普通程序员
  • 原文地址:https://blog.csdn.net/wt334502157/article/details/132587836