首页 > 解决方案 > 有没有办法在年龄范围 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;

标签: sqlpostgresql

解决方案


您将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;

推荐阅读