SQL:如何从 int 中获取左 3 个数字
Posted
技术标签:
【中文标题】SQL:如何从 int 中获取左 3 个数字【英文标题】:SQL: how to get the left 3 numbers from an int 【发布时间】:2010-04-14 18:36:49 【问题描述】:我想从一个整数中检索剩下的 3 个数字以存储在一个表中。例如,如果 int 是 1234567,我想检索 123。我希望第二个数字 (123) 也是一个 int;我不想将任何内容转换为字符串。
(是的,我真的应该使用字符串。但我无法控制问题的这方面。)
谢谢!
【问题讨论】:
您在使用什么数据库引擎? (SQL Server、Oracle、DB2 等) 对于什么数据库?还要澄清一下 - 你希望LEFT(your_column, 3)
的结果是一个整数,而不是一个字符串?
是的,我希望它是一个整数
我在 MS Access 中使用从 SQl 服务器链接的表
【参考方案1】:
对于 SQL Server,最简单的方法肯定是:
SELECT CAST(LEFT(CAST(YourInt AS VARCHAR(100)), 3) AS INT)
转换为字符串,取最左边的三个字符,然后将它们转换回 INT。
纯粹根据数值来做会很麻烦,因为你需要知道你需要去掉多少位数等等......
如果你只想使用纯粹的 INT,你必须构造这样的东西(至少你可以在 SQL Server 中做到这一点——我对 Access 不够熟悉,不知道这是否适用于 Access SQL“方言”):
DECLARE @MyInt INT = 1234567
SELECT
CASE
WHEN @MyInt < 1000 THEN @MyInt
WHEN @MyInt > 10000000 THEN @MyInt / 100000
WHEN @MyInt > 1000000 THEN @MyInt / 10000
WHEN @MyInt > 100000 THEN @MyInt / 1000
WHEN @MyInt > 10000 THEN @MyInt / 100
WHEN @MyInt > 1000 THEN @MyInt / 10
END AS 'NewInt'
但这始终是一个近似值 - 如果你有一个非常非常大的数字怎么办......它可能会从裂缝中消失......
【讨论】:
我要学会更快地打字。这一切都排队等待发布 SELECT (CAST(LEFT(CAST(1234567 AS VARCHAR), 3) AS INT)) :) 如果字符串的长度小于请求的长度,LEFT() 是否有问题?如果是这样,您需要在字符串的 LEFT() 之前添加“000”。 这些都不能在 Access 中工作,除了可能作为传递,但只有当它返回记录集时才有效。 请注意,如果必须考虑负整数,则需要扩展 LEFT() 方法。【参考方案2】:不强制转换成字符串,这样怎么样?
(T-SQL)
select @i / power(10,floor(log10(@i))-2)
如果 int 小于 100,则抛出错误,但似乎可以正常工作。
编辑:要优雅地处理错误,您必须使用 CASE,因为 TSQL 没有 GREATEST() 函数...
select @i / case when @i < 100 then 1 else power(10,floor(log10(@i))-2) end
【讨论】:
虽然字符串转换形式可能表现更好,但对于这类问题,我总是更喜欢基于数学的解决方案。 Jet/ACE 的 SQL 不需要将数字强制转换为字符串,因为它的 Left() 函数会隐式执行此操作。您可能需要也可能不需要将字符串结果强制转换为数字,具体取决于您使用它的目的。我只是不明白为什么人们会避免使用更简单的方法。【参考方案3】:访问SELECT clng(left(cstr(field), 3)) FROM T
应该可以工作。
编辑:事实上我敢打赌它不会关心 cstr()。
【讨论】:
呃,为什么要把一个三位数的数字加长? CInt() 对于 3 位数字就可以了。 CStr() 不是必需的,因为 Left() 隐式地将数值强制转换为字符串进行处理。我不喜欢依赖隐式强制,但依赖于隐式强制可以避免对每一行进行额外的函数调用,如果您在返回大型结果集的查询中执行此操作,这可能是一个重大的性能问题。但我还是不喜欢它。 好吧,如果你要转换为整数,不妨使用 32 位的 呃,为什么?我不知道它有什么不同,但我们不知道它被使用的上下文。将 CLng() 用于您知道是 CInt() 的值违反了我所知道的所有强数据类型的原则。您也可以在 Access 中使用 Val(),但不能通过 OLEDB/ODBC。但我认为这比 CLng() 或 CInt() 效率低。【参考方案4】:;WITH c10 AS
(
SELECT
Number
FROM
MyTable --?? WHERE Number>=1000
UNION ALL
SELECT Number/10 FROM c10 WHERE Number>=1000
)
SELECT Number FROM c10 WHERE Number < 1000
我无法对此进行测试,但它应该可以解决问题。依靠整数除法,迭代直到你最终得到
仅适用于原始 TSQL SQL Server 2005 解决方案
【讨论】:
您在回答已经用表明它正在 Access 中运行的标签进行编辑后发布了此内容,因此为了使您的回答有价值,您需要解释 T-SQL 与 Access 的相关性问题。 @David-W-Fenton:“我在 MS Access 中使用从 SQl 服务器链接的表”-> 所以使用传递查询而不是使用 Jet-SQL。他是否想要第一个 3 个数字?在 Jet SQL 中不使用字符串... @gbn:呃,什么?当然,它可以在 Jet/ACE SQL 中完成,而无需任何直通。为什么您认为避免在所有上下文中受 Jet/ACE SQL 支持的内置函数(如 Left() 和 CLng())很重要,这超出了我的理解。另外,请注意,直通有其局限性,具体取决于它们的用途。 @David-W-Fenton:OP 说“我不想将任何内容转换为字符串。”你读过这个问题吗?如果这么简单,你的答案在哪里...... @gbn:从上下文中可以清楚地看出,当 OP 说“我不想将任何内容转换为字符串”时,他的意思是存储,括号中的语句“是的”清楚地表明了这一点,真的我应该使用字符串。但是我无法控制问题的那个方面。”,这清楚地表明问题不是转换为字符串以获得正确的结果,而是存储或处理结果.【参考方案5】:如果你可以访问 php,你可以使用 substr
echo substr('1234567', 0, 3);然后将字符串转换回int
Converting an integer to a string in PHP
祝你好运!
【讨论】:
他正在使用 Microsoft Access 和 SQL Server(从他的标签中可以看出) 她(抱歉,忍不住……)以上是关于SQL:如何从 int 中获取左 3 个数字的主要内容,如果未能解决你的问题,请参考以下文章