在没有 RIGHT() 的情况下获取 SQL 字段中最右边的字符
getting rightmost characters in a field in SQL without RIGHT()
我正在使用不支持 SQL RIGHT() 函数的旧 AS400,我需要 SELECT 基于数字最右边的 X 个字符的行使用 SQL.
可能是 7 或 8 个字符长
如果我不能使用 RIGHT 并且我不知道数字的确切长度,我怎么能得到我想要的?
以下是一些有用的上下文:
该数字是一个日期,但被存储为一个数字,因此第一个零被数据库删除,导致以零开头的日期,如 01032016 [读取为 01-03-2016] 被修剪为 1032016) .
数据库很大,所以请求所有行而不过滤这个字段会消耗相当多的资源和时间。
将数据库中的日期格式更改为更合理的格式会导致对我不维护的软件进行重大更改,这是关键任务。
是否支持取模?
输入:1032016
// Outputs: 2016
YOURDATEASINT % 10000 AS Year
MOD(YOURDATEASINT, 10000) AS Year
// Outputs: 32016
YOURDATEASINT % 1000000 AS MonthYear
MOD(YOURDATEASINT, 1000000) AS MonthYear
// Outputs: 1032016
YOURDATEASINT % 100000000 AS DayMonthYear
MOD(YOURDATEASINT, 100000000) AS DayMonthYear
SUBSTRING(mystr,character_length(mystr)-x+1,x)
或
SUBSTRING(mystr,character_length(mystr)-x+1)
如果数据存储为数字,则数据库不会去除前导数字。无论您使用什么工具来查询数据,都可以做到这一点。
假设数据存储为压缩或分区小数而不是整数(很可能),然后使用 DIGITS()
将数字转换为固定字符,包括前导零,然后您可以使用 SUBSTR()
令我震惊的是,以数字形式存储的日期甚至不是 YYYYMMDD 格式。因此,对跨越一年以上的这些值的范围进行过滤特别烦人。
如果您有权创建 table 和索引,您可以做的一件事是创建一个日期 table,它简单地列出某个非常大范围内的每个可能的日期。 (150,000 条记录将涵盖 400 多年,按照今天的标准,这是一个很小的 table。)这个 table 将包括多种格式,包括至少一种是真正的 DATE 类型的列,一种是是您要处理的内容(在本例中,是表示 MMDDYYYY 或 DDMMYYYY 的 8 位数字)。然后您可以使用联接来利用 SQL 查询引擎的优势,而不必对数据的每一行执行函数计算(如果您使用-行 SQL).
虽然 substring(digits(date_column),x,y) 是一个选项,但另一个选项是 MOD 函数和除法的组合。例如,要获取年份,请使用:SELECT MOD(date_column,10000)
,要获取日期,请使用:CAST(MOD(date_column,1000000)/10000 AS INT)
,要获取月份,请使用:CAST(date_column/1000000 AS INT)
.
我正在使用不支持 SQL RIGHT() 函数的旧 AS400,我需要 SELECT 基于数字最右边的 X 个字符的行使用 SQL.
可能是 7 或 8 个字符长如果我不能使用 RIGHT 并且我不知道数字的确切长度,我怎么能得到我想要的?
以下是一些有用的上下文:
该数字是一个日期,但被存储为一个数字,因此第一个零被数据库删除,导致以零开头的日期,如 01032016 [读取为 01-03-2016] 被修剪为 1032016) .
数据库很大,所以请求所有行而不过滤这个字段会消耗相当多的资源和时间。
将数据库中的日期格式更改为更合理的格式会导致对我不维护的软件进行重大更改,这是关键任务。
是否支持取模?
输入:1032016
// Outputs: 2016
YOURDATEASINT % 10000 AS Year
MOD(YOURDATEASINT, 10000) AS Year
// Outputs: 32016
YOURDATEASINT % 1000000 AS MonthYear
MOD(YOURDATEASINT, 1000000) AS MonthYear
// Outputs: 1032016
YOURDATEASINT % 100000000 AS DayMonthYear
MOD(YOURDATEASINT, 100000000) AS DayMonthYear
SUBSTRING(mystr,character_length(mystr)-x+1,x)
或
SUBSTRING(mystr,character_length(mystr)-x+1)
如果数据存储为数字,则数据库不会去除前导数字。无论您使用什么工具来查询数据,都可以做到这一点。
假设数据存储为压缩或分区小数而不是整数(很可能),然后使用 DIGITS()
将数字转换为固定字符,包括前导零,然后您可以使用 SUBSTR()
令我震惊的是,以数字形式存储的日期甚至不是 YYYYMMDD 格式。因此,对跨越一年以上的这些值的范围进行过滤特别烦人。
如果您有权创建 table 和索引,您可以做的一件事是创建一个日期 table,它简单地列出某个非常大范围内的每个可能的日期。 (150,000 条记录将涵盖 400 多年,按照今天的标准,这是一个很小的 table。)这个 table 将包括多种格式,包括至少一种是真正的 DATE 类型的列,一种是是您要处理的内容(在本例中,是表示 MMDDYYYY 或 DDMMYYYY 的 8 位数字)。然后您可以使用联接来利用 SQL 查询引擎的优势,而不必对数据的每一行执行函数计算(如果您使用-行 SQL).
虽然 substring(digits(date_column),x,y) 是一个选项,但另一个选项是 MOD 函数和除法的组合。例如,要获取年份,请使用:SELECT MOD(date_column,10000)
,要获取日期,请使用:CAST(MOD(date_column,1000000)/10000 AS INT)
,要获取月份,请使用:CAST(date_column/1000000 AS INT)
.