sql - 有没有办法在年龄范围 SQL 查询中处理强制转换类型 varchar 和 INT?
问题描述
我正在编写一个查询来计算年龄范围,我在字符串中包含年龄数据,如“21”、“31”等。所以我使用CAST(age AS INT)
将年龄转换为整数,但在某些情况下,年龄被给出为“ NA',在这种情况下,我的CAST(age AS INT)
失败,因为 'NA' 无法转换为带有错误的整数
整数的输入语法无效
有没有办法处理这种情况?
SELECT
'Under 10' AS Age,
SUM(CASE WHEN CAST(age AS INT) < 10 THEN 1 ELSE 0 END) AS People
FROM
people
UNION ALL
SELECT
'11-20', SUM(CASE WHEN CAST(age AS INT) BETWEEN 11 AND 20 THEN 1 ELSE 0 END)
FROM
people
UNION ALL
SELECT
'21-30', SUM(CASE WHEN CAST(age AS INT) BETWEEN 21 AND 30 THEN 1 ELSE 0 END)
FROM
people;
解决方案
您将where
为此查询使用子句,而不是条件聚合:
SELECT 'Under 10' as Age, COUNT(*) as People
FROM people
WHERE age < 10
UNION ALL
SELECT '11-20', COUNT(*)
FROM people
WHERE age BETWEEN 11 AND 20
UNION ALL
SELECT '21-30', COUNT(*)
FROM people
WHERE age BETWEEN 21 AND 30;
由于 SQL 中的类型转换规则,age
将转换为数字进行比较。这是隐式转换,我不喜欢。如何显式且方便地进行转换取决于数据库。例如
- Postgres:
age::int
- MySQL:
(age + 0)
比隐式比较更糟糕的是使用了错误的数据类型。 age
应该是一个数字,所以你应该修复数据:
alter table people alter column age int;
而且,age
一般根本不应该在数据库中!如果每天都在变化。出生日期或出生年份更合适。
编辑:
鉴于'NA'
(确实应该是NULL
)的存在,我建议:
您将where
为此查询使用子句,而不是条件聚合:
SELECT 'Under 10' as Age, COUNT(*) as People
FROM people
WHERE NULLIF(age, 'NA')::int < 10
UNION ALL
SELECT '11-20', COUNT(*)
FROM people
WHERE NULLIF(age, 'NA')::int BETWEEN 11 AND 20
UNION ALL
SELECT '21-30', COUNT(*)
FROM people
WHERE NULLIF(age, 'NA')::int BETWEEN 21 AND 30;
或者,更好的是,修复数据!
update people
set age = NULL
where age = 'NA';
alter table people alter column age int;
推荐阅读
- java - 在 Spring Boot 中可分页
- python - 如何从 WTForms 中删除建议
- javascript - 使用 vue 根据元素 ui 树中的文件夹选择过滤文件
- r - 访问Rstudio中具有“useMethod(”packagefunction“)的函数的整个源代码?
- c++ - 在 C++ 中引用 string::string 中的任何字符
- delphi - 如何确定程序是否仅接受文件或文件列表作为参数?
- mongodb - 在构面内完成计数文档时返回空数组
- asp.net - 如何下载带有链接的 aspnetForm 页面
- php - 我正在尝试获取自动创建的用户 ID
- reactjs - 在此处获取父元素语法错误。找不到?