SQL解码 - SELECT&哪里

时间:2014-11-12 14:45:45

标签: sql oracle select where decode

我有一个我认为需要这样的查询(解码会更大)

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中解码吗? 如果我转换用户选择以匹配数据库而不是尝试解码会更好吗?虽然我的数据库有两种不同类型的数据作为标记,但我试图将其转换为单一的不同类型,这也是用户选择的类型。

2 个答案:

答案 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,