Oracle:CASE 等同于 DECODE
Oracle: CASE equivalent of DECODE
对于下面的示例,我在编写(和理解)等效于 DECODE 的 CASE 时遇到问题。
假设我们有以下 table.
CREATE TABLE Employee(
first_name VARCHAR2(15) CONSTRAINT nn_first_name NOT NULL,
last_name VARCHAR2(15) CONSTRAINT nn_last_name NOT NULL,
sex VARCHAR2(1) CONSTRAINT check_sex CHECK(sex IN ('M', 'F')),
ID VARCHAR2(15) CONSTRAINT pk_ID PRIMARY KEY,
boss_ID VARCHAR2(15) CONSTRAINT fk_ID_empl_to_empl REFERENCES Employee(ID));
Name Null Type
---------- -------- ------------
FIRST_NAME NOT NULL VARCHAR2(15)
LAST_NAME NOT NULL VARCHAR2(15)
SEX VARCHAR2(1)
ID NOT NULL VARCHAR2(15)
BOSS_ID VARCHAR2(15)
现在,我想运行一份显示男性员工上司和下属信息的报表。如果员工没有下属,则显示(null),没有老板的员工也是如此-整个公司的老板。
以上可以使用DECODE实现:
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.ID = E2.boss_ID
WHERE
DECODE(E1.ID, NULL, 'M', E1.sex) = 'M' AND
DECODE(E2.ID, NULL, 'M', E2.sex) = 'M';
上述函数会将所有 NULL
值更改为 'M'
并匹配其中 'M' = 'M'
的行用于“Boss
”和“Subordinates
”列。
我无法使用 CASE
编写等效语句。我得到的那个:
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.id = E2.boss_id
WHERE
(CASE
WHEN E1.ID = 'NULL' THEN 'M' ELSE E1.sex END) = 'M'
AND
(CASE
WHEN E2.ID = 'NULL' THEN 'M' ELSE E2.sex END) = 'M';
我似乎误解了 CASE
的用法,因为它 returns 行较少 - 没有 (null)
值。
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.id = E2.boss_id
WHERE
(CASE
WHEN E1.ID is null THEN 'M' ELSE E1.sex END) = 'M'
AND
(CASE
WHEN E2.ID is null THEN 'M' ELSE E2.sex END) = 'M';
将值与 null 进行比较时,使用 IS NULL 和 IS NOT NULL 。
您不需要 case
或 decode
:
WHERE (E1.ID IS NULL OR E1.sex = 'M') AND
(E2.ID IS NULL OR E2.sex = 'M')
您的逻辑也可以工作,只是您将 NULL
放在单引号中。四个字符 N,U,L,L 的字符串值与内置值不同 NULL
.
对于下面的示例,我在编写(和理解)等效于 DECODE 的 CASE 时遇到问题。
假设我们有以下 table.
CREATE TABLE Employee(
first_name VARCHAR2(15) CONSTRAINT nn_first_name NOT NULL,
last_name VARCHAR2(15) CONSTRAINT nn_last_name NOT NULL,
sex VARCHAR2(1) CONSTRAINT check_sex CHECK(sex IN ('M', 'F')),
ID VARCHAR2(15) CONSTRAINT pk_ID PRIMARY KEY,
boss_ID VARCHAR2(15) CONSTRAINT fk_ID_empl_to_empl REFERENCES Employee(ID));
Name Null Type
---------- -------- ------------
FIRST_NAME NOT NULL VARCHAR2(15)
LAST_NAME NOT NULL VARCHAR2(15)
SEX VARCHAR2(1)
ID NOT NULL VARCHAR2(15)
BOSS_ID VARCHAR2(15)
现在,我想运行一份显示男性员工上司和下属信息的报表。如果员工没有下属,则显示(null),没有老板的员工也是如此-整个公司的老板。
以上可以使用DECODE实现:
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.ID = E2.boss_ID
WHERE
DECODE(E1.ID, NULL, 'M', E1.sex) = 'M' AND
DECODE(E2.ID, NULL, 'M', E2.sex) = 'M';
上述函数会将所有 NULL
值更改为 'M'
并匹配其中 'M' = 'M'
的行用于“Boss
”和“Subordinates
”列。
我无法使用 CASE
编写等效语句。我得到的那个:
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.id = E2.boss_id
WHERE
(CASE
WHEN E1.ID = 'NULL' THEN 'M' ELSE E1.sex END) = 'M'
AND
(CASE
WHEN E2.ID = 'NULL' THEN 'M' ELSE E2.sex END) = 'M';
我似乎误解了 CASE
的用法,因为它 returns 行较少 - 没有 (null)
值。
SELECT E1.last_name Boss,
E2.last_name Subordinate
FROM Employee E1 FULL JOIN Employee E2
ON E1.id = E2.boss_id
WHERE
(CASE
WHEN E1.ID is null THEN 'M' ELSE E1.sex END) = 'M'
AND
(CASE
WHEN E2.ID is null THEN 'M' ELSE E2.sex END) = 'M';
将值与 null 进行比较时,使用 IS NULL 和 IS NOT NULL 。
您不需要 case
或 decode
:
WHERE (E1.ID IS NULL OR E1.sex = 'M') AND
(E2.ID IS NULL OR E2.sex = 'M')
您的逻辑也可以工作,只是您将 NULL
放在单引号中。四个字符 N,U,L,L 的字符串值与内置值不同 NULL
.