当数据库把数字字段当成文本读取,就会一个字符一个字符地排序,于是 100 排在 9 前面,像”小于 20”这样的条件也会给出错误结果。修正方法是清理数据,在导入步骤设定正确的字段类型,然后拿一些记录与来源核对。
本页配合数据库结构与验证,以及识别数字被当成文本的错误这节课。步骤与具体软件无关,因为各产品和版本的菜单名称会变。
到底哪里出了问题?
每个数据库字段都有数据类型。文本字段存放字符,从左到右比较。数字字段存放数值,按大小比较。
导入时,软件会根据看到的值猜测类型,或使用你选定的类型。
常见原因有三个:
- 某一行里有多余字符,例如”RM 2.00”、末尾空格,或”1,200”里的逗号。一个坏值就可能让整列变成文本。
- **在导入画面接受了默认的文本类型。**软件给每一列都提供文本,你直接点了下一步。
- 本该是文本的值被当成数字,这是相反的问题:电话号码丢了开头的零。
完整例子
一份虚构的食堂文件有四行。
| ItemID | Item | Price | Stock |
|---|---|---|---|
| C01 | Nasi lemak | 3.50 | 12 |
| C02 | Teh ais | RM 2.00 | 9 |
| C03 | Roti canai | 1.50 | 100 |
| C04 | Kuih | 0.80 | 40 |
学生导入文件时,把所有列都留在文本类型。然后把 Stock 升序排序,得到 100、12、40、9。文本排序先比较第一个字符:“100”和”12”都以 1 开头,而”0”比”2”小,所以 100 排在 12 前面。接着 40 和 9,因为 4 比 9 小。
查询 Stock < 20 在文本状态下返回 100 和 12,却漏掉 9,因为”9”比”2”大。正确的数值答案是 12 和 9。
修正步骤:
- 保留原始文件,在副本上操作。
- **清理来源:**把”RM 2.00”改成 2.00。RM 用数据库的货币格式显示,不要写在值里面。
- **导入时设定类型:**ItemID 文本,Item 文本,Price 数字(小数),Stock 数字(整数)。
- **核对:**把 Stock 升序和降序各排一次。现在升序应该是 9、12、40、100。
- **重新运行查询:**Stock < 20 应该只返回 12 和 9。
你可以用只读 SQL 练习实验室里的虚构数据,练习排序和筛选的概念。
要留意的错误
有学生在导入后把 Price 字段改成数字,结果 RM 2.00 那个值变成空白,就以为软件坏了。其实是这个值无法读成数字,所以被丢弃或标记。正确做法是先清理值,再转换,并且始终拿记录与原始文件比对。
哪些像数字的值应该保持为文本?
| 值 | 类型 | 原因 |
|---|---|---|
| 以 0 开头的电话号码 | 文本 | 开头的零很重要,也不会拿来计算 |
| 邮政编码 08000 | 文本 | 开头的零很重要 |
| 学生编号 S0042 | 文本 | 含有字母和代码格式 |
| 库存数量 | 数字 | 按大小排序和比较 |
| 价格 | 数字 | 会相加、求平均、比较 |
判断方法很简单:**我会对它做加法、平均或按大小比较吗?**如果会,就用数字类型。
自我检测
1. 库存值 5、40、7 按文本升序排序,会出现什么顺序?
查看答案
文本先比较第一个字符:4 比 5 小,5 比 7 小。所以顺序是 40、5、7。
2. 一列年龄因为有一个单元格写着”16 yrs”而被导入成文本。有哪两种合理的修正?
查看答案
把来源单元格清理成 16,并在导入前把字段类型设为数字;或者在数据库里修正该单元格,再转换类型。两种做法都要拿一些记录与原始文件核对。
3. 为什么电话号码更适合存成文本?
查看答案
它是标识符,不是数量。数字类型可能去掉开头的零,而且你从不会对电话号码做加法或平均。
接下来
可以先练习根据样本值选择字段类型,再做导入一个小型虚构数据集。需要把结果作为证据展示时,ICT 实践任务与证据检查器提供与软件无关的清单,截取显示相关设置的证据这节课则讲截图部分。
知道该看哪里,导入问题就很容易修正;当错误的设置藏在你匆匆点过的画面里,就比较难找。一对一线上 ICT 补习让老师陪你看那一步。