我有一个employee
表格如下:
+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
| emp_id | fname | lname | start_date | end_date | superior_emp_id | dept_id | title | assigned_branch_id |
+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
| 1 | Michael | Smith | 2005-06-22 | NULL | NULL | 3 | President | 1 |
| 2 | Susan | Barker | 2006-09-12 | NULL | 1 | 3 | Vice President | 1 |
| 3 | Robert | Tyler | 2005-02-09 | NULL | 1 | 3 | Treasurer | 1 |
| 4 | Susan | Hawthorne | 2006-04-24 | NULL | 3 | 1 | Operations Manager | 1 |
| 5 | John | Gooding | 2007-11-14 | NULL | 4 | 2 | Loan Manager | 1 |
| 6 | Helen | Fleming | 2008-03-17 | NULL | 4 | 1 | Head Teller | 1 |
| 7 | Chris | Tucker | 2008-09-15 | NULL | 6 | 1 | Teller | 1 |
| 8 | Sarah | Parker | 2006-12-02 | NULL | 6 | 1 | Teller | 1 |
| 9 | Jane | Grossman | 2006-05-03 | NULL | 6 | 1 | Teller | 1 |
| 10 | Paula | Roberts | 2006-07-27 | NULL | 4 | 1 | Head Teller | 2 |
| 11 | Thomas | Ziegler | 2004-10-23 | NULL | 10 | 1 | Teller | 2 |
| 12 | Samantha | Jameson | 2007-01-08 | NULL | 10 | 1 | Teller | 2 |
| 13 | John | Blake | 2004-05-11 | NULL | 4 | 1 | Head Teller | 3 |
| 14 | Cindy | Mason | 2006-08-09 | NULL | 13 | 1 | Teller | 3 |
| 15 | Frank | Portman | 2007-04-01 | NULL | 13 | 1 | Teller | 3 |
| 16 | Theresa | Markham | 2005-03-15 | NULL | 4 | 1 | Head Teller | 4 |
| 17 | Beth | Fowler | 2006-06-29 | NULL | 16 | 1 | Teller | 4 |
| 18 | Rick | Tulman | 2006-12-12 | NULL | 16 | 1 | Teller | 4 |
+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
我正在尝试为出纳员转换数据,如下所示:
SELECT
e.emp_id,
e.fname,
e.lname,
CASE e.title
WHEN 'Head Teller' THEN 'Head Teller'
WHEN 'Teller' AND YEAR(e.start_date) > 2007 THEN 'Teller Trainee'
WHEN 'Teller'AND YEAR(e.start_date) < 2006 THEN 'Experienced Teller'
WHEN 'Teller' THEN 'Teller'
ELSE 'Non-Teller'
END `title`
FROM
employee e
然而像迈克尔史密斯这样的员工出现在Teller Trainee而不是Non-Teller,如下所示:
+--------+----------+-----------+----------------+
| emp_id | fname | lname | title |
+--------+----------+-----------+----------------+
| 1 | Michael | Smith | Teller Trainee |
| 2 | Susan | Barker | Teller Trainee |
| 3 | Robert | Tyler | Teller Trainee |
| 4 | Susan | Hawthorne | Teller Trainee |
| 5 | John | Gooding | Teller Trainee |
| 6 | Helen | Fleming | Head Teller |
| 7 | Chris | Tucker | Teller Trainee |
| 8 | Sarah | Parker | Teller Trainee |
| 9 | Jane | Grossman | Teller Trainee |
| 10 | Paula | Roberts | Head Teller |
| 11 | Thomas | Ziegler | Teller Trainee |
| 12 | Samantha | Jameson | Teller Trainee |
| 13 | John | Blake | Head Teller |
| 14 | Cindy | Mason | Teller Trainee |
| 15 | Frank | Portman | Teller Trainee |
| 16 | Theresa | Markham | Head Teller |
| 17 | Beth | Fowler | Teller Trainee |
| 18 | Rick | Tulman | Teller Trainee |
+--------+----------+-----------+----------------+
注意:使用搜索案例表达式时,如下所示:
SELECT
e.emp_id,
e.fname,
e.lname,
CASE
WHEN e.title = 'Head Teller'
THEN 'Head Teller'
WHEN e.title = 'Teller'
AND YEAR(e.start_date) > 2007
THEN 'Teller Trainee'
WHEN e.title = 'Teller'
AND YEAR(e.start_date) < 2006
THEN 'Experienced Teller'
WHEN e.title = 'Teller'
THEN 'Teller'
ELSE 'Non-Teller'
END `title`
FROM
employee e
输出正确如下:
+--------+----------+-----------+--------------------+
| emp_id | fname | lname | title |
+--------+----------+-----------+--------------------+
| 1 | Michael | Smith | Non-Teller |
| 2 | Susan | Barker | Non-Teller |
| 3 | Robert | Tyler | Non-Teller |
| 4 | Susan | Hawthorne | Non-Teller |
| 5 | John | Gooding | Non-Teller |
| 6 | Helen | Fleming | Head Teller |
| 7 | Chris | Tucker | Teller Trainee |
| 8 | Sarah | Parker | Teller |
| 9 | Jane | Grossman | Teller |
| 10 | Paula | Roberts | Head Teller |
| 11 | Thomas | Ziegler | Experienced Teller |
| 12 | Samantha | Jameson | Teller |
| 13 | John | Blake | Head Teller |
| 14 | Cindy | Mason | Teller |
| 15 | Frank | Portman | Teller |
| 16 | Theresa | Markham | Head Teller |
| 17 | Beth | Fowler | Teller |
| 18 | Rick | Tulman | Teller |
+--------+----------+-----------+--------------------+
我对第一个查询无效的原因感到茫然。
答案 0 :(得分:4)
基于MySQL doc,它应该是
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE
OR
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE
不是两者兼而有之,我的猜测是MySQL没有将其标记为错误,但不会按照您的想法行事。
来自Robert Rocha的评论:
SQL中有两种CASE
语法形式。您可以这样写CASE
:
CASE
WHEN case_value = (when_expr1) THEN ...
WHEN case_value = (when_expr2) THEN ...
但是,如果您的所有WHEN子句与具有简单相等条件的相同左侧case_value
进行比较,那么这似乎是多余的输入。为方便起见,CASE
也支持简写:
CASE case_value
WHEN when_expr1 THEN ...
WHEN when_expr2 THEN ...
这很好。但是您使用CASE
并不像预期的那样工作的原因是您假设您可以使用AND
表达式,但优先顺序不起作用就像你想的那样。
您写道:
CASE e.title
WHEN 'Head Teller' THEN ...
WHEN 'Teller' AND YEAR(e.start_date) > 2007 THEN ...
你认为它会像你做的一样工作:
CASE
WHEN (e.title = 'Head Teller') THEN ...
WHEN (e.title = 'Teller') AND (YEAR(e.start_date) > 2007) THEN ...
但事实上,当您将e.title
放在开头时,它会隐式覆盖优先级,就像您已经完成一样:
CASE
WHEN e.title = ('Head Teller') THEN ...
WHEN e.title = ('Teller' AND YEAR(e.start_date) > 2007) THEN ...
与布尔表达式比较实际上是一种合法的比较:
A = (B AND C)
表达式B AND C
是布尔值,因此它将计算为true或false(实际上是MySQL中的整数值1和0)。
因此,您要将A
与1或0进行比较。因为在您的情况下A
是e.title
,我猜它是一个字符串,那个字符串&# 39; s数值将为0(MySQL中的任何字符串都可以通过其前导数字字符(如果有)计算为数值,如果没有,则为0)。
因此,您的e.title
将被视为0,并且它与之比较的表达式将为0,因为'Teller'
被视为数值0,用于布尔评估。
由于0 = 0
为真,因此CASE
中的条件必然为真。
底线:如果您有复杂的条件,则无法使用CASE
语法的简写版本。明确写出每个条件。
答案 1 :(得分:0)
来自:http://www.mysqltutorial.org/mysql-case-statement/
简单的CASE语句只允许您将表达式的值与一组不同的值进行匹配。为了执行更复杂的匹配(例如范围),可以使用搜索的CASE语句。搜索到的CASE语句等同于IF语句,但是它的构造更具可读性。