我有一个我认为需要这样的查询(解码会更大)
SELECT
firstName,
lastName,
decode(mathMrk, 80, 'A', mathMrk) as decodeMath,
decode(engMrk, 80, 'A', engMrk) as decodeEng,
FROM table
WHERE
decode(mathMrk, 80, 'A', mathMrk) IN ('A','B','C')
OR decode(engMrk, 80, 'A', engMrk) IN ('A','B');
或者哪里可以?
WHERE
decodeMath IN ('A','B','C')
OR decodeEng IN ('A','B');
目标是以某种格式获得所有学生分数,但是如果说用户希望看到只有A' A'用英语或者A'在数学中(根据选择和在哪里的原因)他们只看到那些学生 - 但所有相关的标记
基本上问题是:如果我在SELECT中解码和别名,我还需要在WHERE中解码吗? 如果我转换用户选择以匹配数据库而不是尝试解码会更好吗?虽然我的数据库有两种不同类型的数据作为标记,但我试图将其转换为单一的不同类型,这也是用户选择的类型。
答案 0 :(得分:2)
将其包装成CASE子句。您还可以在WHERE子句中使用CASE。
这是一个应该在任何Oracle架构上运行的(简单)工作示例 我将object_id转换为1到100的等级。
with grades as
(select object_name as student,
mod (object_id, 99) + 1 as mathmark,
case
when mod (object_id, 100) + 1 between 0 and 20 then 'F'
when mod (object_id, 100) + 1 between 21 and 40 then 'D'
when mod (object_id, 100) + 1 between 41 and 60 then 'C'
when mod (object_id, 100) + 1 between 61 and 80 then 'B'
when mod (object_id, 100) + 1 between 81 and 100 then 'A'
end
as mathdecode
from user_objects)
select *
from grades
where mathdecode in ('A', 'B')
答案 1 :(得分:1)
您不能在where
子句中的选择列表中使用别名,只能在order by
子句中使用。原因是SQL是按步骤处理的。首先计算相关行(where
子句),然后计算选定的字段(SELECT
子句),最后排序行(order by
子句)。
有几种方法可以解决这个问题。 最常见的方法是使用视图(显式或隐式):
SELECT
firstName,
lastName,
decodeMath,
decodeEng,
FROM
(SELECT
firstName,
lastName,
decode(mathMrk, 80, 'A', mathMrk) as decodeMath,
decode(engMrk, 80, 'A', engMrk) as decodeEng,
FROM table) tableview
WHERE
decodeMath IN ('A','B','C')
OR decodeEng IN ('A','B');
您可以在选择中拥有视图的所有代码(如上例所示),也可以单独创建视图,然后像使用表一样使用它。如果您需要在多个SQL中使用相同的视图,后者非常方便。
我还建议你创建一个从mrk到年级的翻译功能。
CREATE OR REPLACE FUNCTION decodeMrk(mrk in Integer) RETURN Varchar2(1) IS
BEGIN
return CASE WHEN mrk >= 80 THEN 'A'
WHEN mrk >= 60 THEN 'B' ... -- and so on
END;
END;
然后您可以在视图中使用它:
decodeMrk(mathMrk) as decodeMath,