2017-06-05 107 views
1

虽然我看到更新语句根据现有值更新字段,但找不到类似于此场景的任何内容:如何通过确定字段中的每个数字来更新字段值?

假设您的表格只有一列数字(4)类型的列。第一条记录中的值为1010.

create table stab(
    nmbr number(4) 
); 

insert into stab values(1010); 

For each digit 
    When the digit is 1 -- add 3 to the digit 
    When the digit is 0 -- add four to the digit 
end 

此操作需要在不使用pl/sql的单个语句中完成。

我认为substr函数需要使用,但不知道如何去完成这个。

在此先感谢。

回答

2
SELECT DECODE(SUBSTR(nmbr,1,1), '1', 1 + 3, '0', 0 + 4) AS Decoded_Nmbr 
FROM stab 
ORDER BY Decoded_Nmbr 

这就是你在做什么之后?

+0

令人怀疑。 OP是在某种更新之后,而不是SELECT语句。另外,我不明白哪里有提到订购任何东西的地方。 – mathguy

+0

@NDin - 这是做你要求的吗?您对每个数字**表示**,但这只会处理第一位数字。你说“更新值”,这是一个SELECT。难怪你不会得到那份工作。 – mathguy

1

所以,你似乎需要将每个0和1转换为4,并将所有其他数字单独保留。这看起来像一个字符串操作(并且对“数字”本身的引用表明了同样的事情)。因此,将数字转换为字符串,使用Oracle TRANSLATE函数(请参阅文档),然后转换回数字。

update stab 
set nmbr = to_number(translate(to_char(nmbr, '9999'), '01', '44')) 
; 
-1

假设它始终是一个4位数#;你可以使用子像下面 - Postgres的SQL例如

SELECT CASE 
     WHEN a = 0 THEN a + 4 
     ELSE a + 3 
     end AS a, 
     CASE 
     WHEN b = 0 THEN b + 4 
     ELSE b + 3 
     end AS b, 
     CASE 
     WHEN c = 0 THEN c + 4 
     ELSE c + 3 
     end AS c, 
     CASE 
     WHEN d = 0 THEN d + 4 
     ELSE c + 3 
     end AS d 
FROM (SELECT Substr('1010', 1, 1) :: INT AS a, 
       Substr('1010', 2, 1) :: INT b, 
       Substr('1010', 3, 1) :: INT c, 
       Substr('1010', 4, 1) :: INT d)a 

---其他选项可(试图在PostgreSQL :))使用regexp_split_to_table进行分裂数;再加入个人基础上,每个数字case语句,然后CONCAT数字回字符串

SELECT array_to_string (array 
     (
       select 
        case 
          WHEN val = 0 THEN val +4 
          ELSE val +3 
        END 
       FROM (
          SELECT regexp_split_to_table ('101010','') ::INT val 
        ) a 
     ) ,'') 
+0

为什么提供一个Postgres解决方案(这绝对不会在Oracle中工作),当OP明确将其标记为Oracle并在帖子中提到PL/SQL时(意思是说,它确实是Oracle,这不是错误)? – mathguy

+0

感谢您的回复!这实际上是一个面试问题,他们指出应该使用Oracle上的SQL来完成,而不使用PL/SQL。 –

+0

您的输入真的有帮助,我修改了脚本,如下所示,并找到更新多个记录的方法。下面的脚本只能在单个记录上工作: –

0

我的回答面试问题将是该数据库的设计违反了规范化规则(即一个不好的设计),不会有这样的“更新异常“,如果设计得当的话。话虽如此,可以很容易地用一个表达式来完成,该表达式使用单行函数的各种组合和所需的算术运算。