目录
背景
在这里,我们将检查CASE如何在任何允许有效表达式的语句或子句中使用的示例。例如,我们通常在一些语句中使用CASE,例如SELECT,UPDATE,DELETE和SET。CASE也可以与JOIN,WHERE,ORDER BY和HAVING子句一起使用。让我们检查一些示例。
CASE类型
CASE有两种类型:
- 简单CASE:仅允许相等性检查
- 搜索CASE:允许多次检查
简单CASE
CASE Expression
WHEN Value1 THEN Result1
WHEN Value2 THEN Result2
…
ELSE Result
END
DECLARE @userTypeId INT = 2;
DECLARE @userType VARCHAR(100);
/*Simple CASE*/
SET @userType = CASE @userTypeId
WHEN 1 THEN 'Admin'
WHEN 2 THEN 'User'
ELSE 'Unknown'
END;
SELECT @userType;
搜索CASE
CASE
WHEN BooleanExpression1 THEN Result1
WHEN BooleanExpression2 THEN Result2
…
ELSE Result
END
DECLARE @userTypeId INT = 2;
DECLARE @userType VARCHAR(100);
/*Searched CASE*/
SET @userType = CASE
WHEN @userTypeId = 1 THEN 'Admin'
WHEN @userTypeId = 2 THEN 'User'
ELSE 'Unknown'
END;
SELECT @userType;
或者,我们也可以做:
DECLARE @inputNumber INT = 2
DECLARE @result NVARCHAR(MAX);
SELECT
@result =
CASE
WHEN ISNUMERIC(@inputNumber) = 1 AND @inputNumber % 2 = 0 THEN 'Even'
WHEN ISNUMERIC(@inputNumber) = 1 AND @inputNumber % 2 = 1 THEN 'Odd'
ELSE 'Not Number'
END;
SELECT @result AS Result;
使用变量
使用Switch开关
DECLARE @userTypeId INT = 2; /*set any number*/
DECLARE @userType VARCHAR(100);
SET @userType = CASE @userTypeId
WHEN 1 THEN 'Admin'
WHEN 2 THEN 'User'
ELSE 'Unknown'
END;
SELECT @userType;
多重比较
DECLARE @inputNumber INT = 2
DECLARE @result NVARCHAR(MAX);
SELECT
@result =
CASE
WHEN ISNUMERIC(@inputNumber) = 1 AND @inputNumber % 2 = 0 THEN 'Even'
WHEN ISNUMERIC(@inputNumber) = 1 AND @inputNumber % 2 = 1 THEN 'Odd'
ELSE 'Not Number'
END;
SELECT @result AS Result;
使用SELECT语句
使用Switch开关
/*use like switch*/
SELECT
Id,
CASE Id
WHEN 1 THEN 'Admin'
WHEN 2 THEN 'User'
ELSE 'Anonymous'
END
FROM (
VALUES (1), (2), (NULL)
) AS Roles(Id)
多重比较
/*multiple compare*/
SELECT
NumberValue,
CASE
WHEN ISNUMERIC(NumberValue) = 1 AND NumberValue % 2 = 0 THEN 'Even'
WHEN ISNUMERIC(NumberValue) = 1 AND NumberValue % 2 = 1 THEN 'Odd'
ELSE 'Not Number'
END
FROM(
VALUES ('1'), ('2'), ('A'), (NULL)
) AS NumberList(NumberValue)
使用WHERE子句
以下是我们的表格和数据:
/*with where*/
DECLARE @tblUserPoints TABLE
(
Name VARCHAR(100),
UserType VARCHAR(100),
Points INT
);
INSERT
INTO @tblUserPoints
VALUES
('Dan', 'Sa', 90000), /*will be selected*/
('Dan1', 'Sa', 80000),
('Ben', 'Admin', 70000), /*will be selected*/
('Ben1', 'Admin', 60000),
('Kim', 'User', 50000), /*will be selected*/
('Kim1', 'User', 40000);
CASE而不是OR
下面是常规条件WHERE查询的示例:
/*regular 'OR' condition*/
SELECT *
FROM @tblUserPoints
WHERE (UserType = 'Sa' AND Points > 80000)
OR (UserType = 'Admin' AND Points > 60000)
OR (UserType = 'User' AND Points > 40000)
使用以下CASE方法重写上述查询:
/*using 'CASE' instated of 'OR'*/
SELECT *
FROM @tblUserPoints
WHERE (
CASE
WHEN UserType = 'Sa' AND Points > 80000 THEN 1
WHEN UserType = 'Admin' AND Points > 60000 THEN 1
WHEN UserType = 'User' AND Points > 40000 THEN 1
ELSE NULL
END
) IS NOT NULL
和我们处理AND条件的方法一样。
根据标志在条件之间切换
在这里,取决于@flag,我们实际上是在WHERE条件之间切换的值:
/*switch between conditions depending on a flag*/
DECLARE @flag VARCHAR(50);
--SET @flag = 'Best';
--SET @flag = 'Better';
SET @flag = 'Good';
SELECT *
FROM @tblUserPoints
WHERE (
CASE
WHEN @flag = 'Best' AND Points >= 80000 THEN 1
WHEN @flag = 'Better' AND Points >= 60000 AND Points < 80000 THEN 1
WHEN @flag = 'Good' AND Points >= 40000 AND Points < 60000 THEN 1
ELSE NULL
END
) IS NOT NULL
使用JOIN和ON子句
我们的表格和数据:
/*data*/
DECLARE @tblReputationTotal TABLE
(
TotalPoint INT NULL,
Reputation VARCHAR(100)
);
DECLARE @tblReputation TABLE
(
Point INT NULL, /*sa*/
RankPosition INT NULL, /*admin*/
Rating INT NULL, /*user*/
Reputation VARCHAR(100)
);
DECLARE @tblUserPoint TABLE
(
Name VARCHAR(100),
UserType VARCHAR(100),
Point INT NULL,
RankPosition INT NULL,
Rating INT NULL
);
INSERT
INTO @tblReputationTotal (TotalPoint, Reputation)
VALUES
(90000, 'Best'),
(70000, 'Better'),
(50000, 'Good');
INSERT
INTO @tblReputation (Point, RankPosition, Rating, Reputation)
VALUES
(90000, NULL, NULL, 'Good Sa'),
(NULL, 70000, NULL, 'Good Admin'),
(NULL, NULL, 50000, 'Good User');
INSERT
INTO @tblUserPoint (Name, UserType, Point, RankPosition, Rating)
VALUES
('Dan', 'Sa', 90000, NULL, NULL), /*will be selected, Point*/
('Dan1', 'Sa', 80000, NULL, NULL),
('Ben', 'Admin', NULL, 70000, NULL), /*will be selected, RankPosition*/
('Ben1', 'Admin', NULL, 60000, NULL),
('Kim', 'User', NULL, NULL, 50000), /*will be selected, Rating*/
('Kim1', 'User', NULL, NULL, 40000);
在这里,根据UserType列值,我们选择join列:
/*query*/
SELECT u.*, r.Reputation
FROM @tblUserPoint AS u
JOIN @tblReputation AS r
ON CASE
WHEN u.UserType = 'Sa' AND u.Point = r.Point THEN 1
WHEN u.UserType = 'Admin' AND u.RankPosition = r.RankPosition THEN 1
WHEN u.UserType = 'User' AND u.Rating = r.Rating THEN 1
ELSE 0
END = 1;
或者,我们也可以做:
/*query*/
SELECT u.*, r.Reputation
FROM @tblReputationTotal AS r
JOIN @tblUserPoint AS u
ON r.TotalPoint =
CASE
WHEN u.UserType = 'Sa' THEN u.Point
WHEN u.UserType = 'Admin' THEN u.RankPosition
WHEN u.UserType = 'User' THEN u.Rating
ELSE 0 /*can remove ELSE or set to -1. Don't set it to NULL*/
END
使用Update
DECLARE @tblBalance TABLE (Amount INT NULL, NumberType VARCHAR(100) NULL);
INSERT INTO @tblBalance(Amount) VALUES (1), (2), (3), (4), (NULL);
/*update*/
UPDATE @tblBalance
SET NumberType = CASE
WHEN Amount % 2 = 1 THEN 'Odd'
WHEN Amount % 2 = 0 THEN 'Even'
ELSE 'Null Value'
END;
SELECT * FROM @tblBalance;
使用ORDER BY
我们的表格和数据:
/*data*/
DECLARE @tblEmployee TABLE
(
Id INT,
UserName VARCHAR(100),
Email VARCHAR(100)
);
INSERT
INTO @tblEmployee (Id, UserName, Email)
VALUES
(1, 'Dan', 'Dan@gmail.com'),
(2, 'Hen', 'Han@gmail.com'),
(3, 'Ben', 'Ben@gmail.com');
DECLARE @orderFilter VARCHAR(100);
SET @orderFilter = 'LoginName';
--SET @orderFilter = 'Email';
为了管理order,我们使用order指示器标志@orderFilter。
@orderFilter将保存用于对特定数据集进行排序的预期列名或逻辑。
不同的列但相同的顺序
在这里,我们在UserName或Email或None('')列之间切换,但使用相同的顺序DESC:
SELECT *
FROM @tblEmployee
ORDER BY
(
CASE @orderFilter
WHEN 'LoginName' THEN UserName
WHEN 'Email' THEN Email
ELSE '' /*need varchar, type as username
and email are varchar*/
END
) DESC, /*can do individual column wise,
check next query*/
Id ASC
列明智顺序
它与前面的示例略有不同。在这里,order类型可以特定于每一列。
SELECT *
FROM @tblEmployee
ORDER BY
CASE WHEN @orderFilter = 'LoginName' THEN UserName END DESC,
CASE WHEN @orderFilter = 'Email' THEN Email END ASC,
Id ASC
将按顺序,UserName将按DESC排序, Email将按ASC排序,这取决于列选择标志@orderFilter的值。
其他
- With GROUP BY SQL CASE Statement - Simple and Searched Forms - Essential SQL
- With HAVING
局限性
- 在布尔表达式中不支持OR,而是使用IN()代替OR
- 避免嵌套CASE,SQL Server只允许10个级别的CASE嵌套表达式。而是使用更多WHEN
引用
- Core:CASE (Transact-SQL) - SQL Server | Microsoft Learn
- Join:sql - Can I use CASE statement in a JOIN condition? - Stack Overflow
- Order:sql - CASE WHEN statement for ORDER BY clause - Stack Overflow
https://www.codeproject.com/Tips/1276985/SQL-Server-CASE-with-Different-Clause
462

被折叠的 条评论
为什么被折叠?



