首页 > 解决方案 > 如何通过修改列使用 order by

问题描述

有一个带有年龄列的表。此列的值是 varchar,因为 1 岁以下的人的年龄以月为单位保存,并带有额外的“m”(9 个月大 -> '9m')

我知道这通常是一个坏主意,应该坚持出生日期,但在这种情况下,年龄是指历史上特定日期的年龄 - 另外这是课程的一部分,重点是学习如何处理“奇怪”的数据。

我的第一个想法是在所有不是纯数字的年龄上加上前导零:

SELECT * 
FROM db 
ORDER BY REPLACE(age, (IF ISNUMERIC(age) age ELSE CONCAT('0', age))) DESC;

然而,这不是一个有效的 SQL 语句,我的其他尝试也不是。问题是:如何在ORDER BY不更改数据库的情况下调整用于的值?

另一种方法是仅选择具有纯数字年龄值的行,并为其余行单独选择分别对它们进行排序,然后将它们组合起来。

我对此的看法如下:

(SELECT name, age 
 FROM titanic 
 WHERE ISNUMERIC(age) 
 ORDER BY age DESC) 
UNION 
(SELECT name, age 
 FROM titanic 
 WHERE NOT ISNUMERIC(age) 
 ORDER BY age);

这实际上是有效的,或者至少它给了我一个结果。但在结果中,我真的看不到订单发生了什么,看起来UNION一切都撤消了。

在此先感谢,将采取任何提示,甚至只是我应该研究的函数/方法的名称!

标签: sqlpostgresqlsql-order-by

解决方案


我会使用“Case When”结构和“Order by”中的一些转换来获得这两种年龄的总月数。

Select name, age
From tbl
Where age SIMILAR TO '[1-9][0-9]*' Or
      age SIMILAR TO '[1-9][0-2]?m'
Order by Case When age SIMILAR TO '[1-9][0-2]?m' Then Substring(age,1,CHAR_LENGTH(age)-1)::int
              When age SIMILAR TO '[1-9][0-9]*' Then age::int * 12 End   

推荐阅读