我有一个表,其中用VARCHAR
将列类型设置为9 BYTE
,但是在此列上应用max函数时,它仅显示最大值为9999,而没有其他值,>
create table test(
ID NUMBER,
NAME VARCHAR2(100 BYTE),
SAL NUMBER,
RANK VARCHAR2(9 BYTE));
Insert into test (ID,NAME,SAL,RANK ) values (1082,'ABC',2082,'9999');
Insert into test (ID,NAME,SAL,RANK ) values (1083,'ABC',2083,'10000');
实际数据:
id NAME SAL RANK
1082 ABC 2082 9999
1083 ABC 2083 10000
查询
select * from test where RANK =(select max(RANK ) from testyy);
输出:
id NAME SAL RANK
1082 ABC 2082 9999
我试图将列设为空并将列修改为INTEGER,然后它可以工作,但是我有疑问为什么它不适用于9 BYTE数据类型
update test set RANK =null where id=1082;
update test set RANK =null where id=1083;
alter table test modify RANK INTEGER;
update test set RANK ='9999' where id=1082;
update test set RANK ='10000' where id=1083;
select * from test where RANK =(select max(RANK) from test);
id NAME SAL RANK
------------------------------------------
1083 ABC 2083 10000
Oracle SQL开发人员没有错误消息
答案 0 :(得分:6)
因为rank
是表中的varchar,并且在这种情况下9999
大于10000
,所以9999
最多。
答案 1 :(得分:3)
按字符串排序时,使用字典顺序,其中100在99之前(与'a'在bb'之前相同),而在按数字排序时,则考虑其值,因此100> 90。
例如:
lapply(.)
答案 2 :(得分:1)
当您将VARCHAR
用作数据类型时,MAX
函数的行为就像数据是文本一样。
在订购文本时,即使“ ALIGATOR”中的字母较多,“ ZEBRA”也位于“ ALIGATOR”之后。将相同的逻辑应用于“ 9999”和“ 10000”,则“ 9999”是两者中的较大者,因为“ 9999”的第一个VARCHAR“ 9”在“ 10000”的第一个VARCHAR“ 1”之后。
答案 3 :(得分:1)
我发布此答案是为了纠正您对表设置的基本误解
您断言此语句将创建一个具有字节数据类型的列:
CREATE TABLE X( Y VARCHAR2(100 BYTE) )
在通常理解的“字节为8位并存储0到255(或0x00到0xFF)之间的数字”的编程概念中,绝对与字节无关。
此列的数据类型为VARCHAR2,即text。不是字节。不是数字。不是数字
BYTE的存在指示oracle使用最多100个字节的存储空间来包含文本。这意味着,如果您插入每个字符需要4个字节的Unicode字符,那么在oracle告诉您您的字符串太长之前,您只能在其中获得25个字符。如果您插入ascii字符(每个字符需要1个字节),那么在oracle告诉您您的字符串太长之前,您将在那里获得100个字符
这里BYTE的补码是CHAR,您在其中告诉oracle“只要您接受长度不超过100个字符的字符串,就可以在磁盘上使用所需的空间”。这意味着oracle将在磁盘上使用100到400字节的空间来存储您的字符
-
其他答案已经涵盖了为什么字符串“ 9999”比字符串“ 10000”更大,但是我确实有一个点点滴滴可以补充为什么:
作为字符的“ 9”位于ASCII表中的位置0x39,因此在数字上为“值” 57(以10为基数的0x39十六进制表示)
'1'作为字符在ASCII表中的位置0x31,因此在数字上为“值” 49(以10为基数的0x31十六进制表示)
当oracle比较字符串(从左到右的语言)并询问“哪个字符串在字母顺序之后/更大时?”从左到右逐个字符地比较
在他的情况下,它扮演第一个角色:
Is '9' greater than '1'?
--> What are the numeric representations of these characters? 57 and 49
--> Is 57 greater than 49?
--> Yes. '9' is greater than '1'.
--> STOP and declare '9999' is bigger than '10000'
它停止了,因为不再需要比较。如果两个字符串都以“ 9”开头,则它们将继续比较第一个字符,而甲骨文将继续比较第二个字符,以便确定哪个是获胜者。等等。
所以您拥有了:9999与'9999'无关-一个是数字,一个是看起来像数字的文本。这个问题与基于数字的比较,字节的最大值等无关。
这纯粹是关于字符串/文本的排序方式,这就是您需要了解的内容
永远不要将要用数学方法处理的数字存储在varchar中;它们会占用更多空间,速度会变慢,并且会导致排序,数学错误,并且每次使用时都需要进行转换