【问题标题】:PadLeft function in T-SQLT-SQL 中的 PadLeft 函数
【发布时间】:2011-07-29 05:52:14
【问题描述】:

我有下表A:

id
----
1
2
12
123
1234

我需要用零填充 id 值:

id
----
0001
0002
0012
0123
1234

我怎样才能做到这一点?

【问题讨论】:

    标签: string tsql


    【解决方案1】:

    我相信这可能就是您想要的:

    SELECT padded_id = REPLACE(STR(id, 4), SPACE(1), '0') 
    
    FROM tableA
    

    或

    SELECT REPLACE(STR(id, 4), SPACE(1), '0') AS [padded_id]
    
    FROM tableA
    

    我没有测试第二个例子的语法。我不确定这是否 100% 有效 - 它可能需要进行一些调整 - 但它传达了如何获得所需输出的总体思路。

    编辑

    为了解决 cmets 中列出的问题...

    @pkr298 - 是的,STR 只适用于数字... OP 的字段是一个 ID...因此只有数字。

    @Desolator - 这当然行不通……第一个参数是 6 个字符长。您可以执行以下操作:

    SELECT REPLACE(STR(id,
    (SELECT LEN(MAX(id)) + 4 FROM tableA)), SPACE(1), '0') AS [padded_id] FROM tableA
    

    理论上这应该移动球门柱……随着数字变大,它应该总是有效……不管它是 1 还是 123456789……

    所以如果你的最大值是 123456... 你会看到 0000123456 如果你的最小值是 1 你会看到 0000000001

    【讨论】:

    • STR() 仅适用于数字(或字符串字段中的数字)。如果您在假设有数字但其中一条记录包含错误(非数字)数据的 varchar 字段上使用此代码,则此代码会中断。在这种情况下,RIGHT() 函数不会中断。
    • STR() 如果数字长度较大,则函数将不起作用(例如,STR(123456, 4) 将返回 ****
    • @Desolator 我已经添加了响应和修复以方便您添加的场景。
    【解决方案2】:

    SQL Server 现在从 2012 版开始支持 FORMAT 函数,所以:

    SELECT FORMAT(id, '0000') FROM TableA
    

    会成功的。

    如果您的 id 或列在 varchar 中并表示您首先转换的数字:

    SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA
    

    【讨论】:

    • 简洁明了,谢谢!鉴于原始问题的日期,这现在应该是官方答案;)
    • 如果 id 是一个字符串,那么你可以先把它转换成整数 -- select format(convert(int,id),'0000')
    • 对不起,但我不赞成,因为这种方式真的很慢。花了整整四秒钟来运行超过 90 行,而接受的答案是即时的。这是一个非常主要的缺点,并且 FORMAT 最多只能用于一到两条记录。否则,由于性能非常差,它毫无用处。
    • @ShadowWizard 我看到使用 FORMAT 具有 1000 行的即时性能。
    • @JohnnyHK 可能是表格设计或其他数据库怪癖,但仍然......事实是,对我来说它真的很慢,而另一种方式很快。
    【解决方案3】:
    declare @T table(id int)
    insert into @T values
    (1),
    (2),
    (12),
    (123),
    (1234)
    
    select right('0000'+convert(varchar(4), id), 4)
    from @T
    

    结果

    ----
    0001
    0002
    0012
    0123
    1234
    
    【解决方案4】:

    旧帖子,但也许这可以帮助某人:

    完成直到它以 4 个非空白字符结束:

    SELECT RIGHT ('0000'+COLUMNNAME, 4) FROM TABLENAME;
    

    在 10 点之前完成:

    SELECT RIGHT ('0000000000'+COLUMNNAME, 10) FROM TABLENAME;
    

    如果列是数字,先用这样的代码将其转换为varchar:

    Select RIGHT('0000'+Convert(nvarchar(20), COLUMNNAME), 4)
    From TABLENAME
    

    并使用数字字段完成直到 10:

    SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;
    

    【讨论】:

    • @SilverM-A,没有在数字前添加 0 的实用程序,因为无论如何它们都会被忽略(毕竟 0003 是 3)。可能您想要完成的是将该数字转换为字符串(varchar),然后使用上述语句。
    • @SilverM-A,如果是这种情况,只需使用“CAST”命令进行转换,例如:SELECT RIGHT('0000000000'+CAST(COLUMNNAME AS VARCHAR), 10) FROM TABLENAME;是这样吗?
    • @MarceloMyara 这应该是答案的一部分,而不仅仅是评论。现在自己添加了。
    • 注意:这是最有效的答案,没有花哨的功能可能会变得非常慢。因此我给了它额外的赏金。
    【解决方案5】:

    试试这个:

    SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]
    

    【讨论】:

      【解决方案6】:

      -- 请查看这些。

      select FORMAT(1, 'd4');
      select FORMAT(2, 'd4');
      select FORMAT(12, 'd4');
      select FORMAT(123, 'd4');
      select FORMAT(1234, 'd4');
      

      --希望对你有帮助

      【讨论】:

      【解决方案7】:

      这适用于字符串、整数和数字:

      SELECT CONCAT(REPLICATE('0', 4 - LEN(id)), id)

      4 是所需的长度。适用于超过 4 位的数字,在 NULL 值上返回空字符串。

      【讨论】:

        【解决方案8】:

        这是我在需要填充值时通常使用的。

        SET @PaddedValue = REPLICATE('0', @Length - LEN(@OrigValue)) + CAST(@OrigValue as VARCHAR)
        

        【讨论】:

          【解决方案9】:

          如果有人仍然感兴趣,我在 DATABASE.GUIDE 上找到了这篇文章:
          Left Padding in SQL Server – 3 LPAD() Equivalents

          简而言之,那篇文章中提到了 3 种方法。
          假设您的 id=12 并且您需要将其显示为 0012。

          方法 1 – 使用 RIGHT() 函数
          第一种方法使用 RIGHT() 函数在添加一些前导零后仅返回字符串的最右边部分。

          SELECT RIGHT('00' + '12', 4);

          结果:
          0012

          方法 2 - 使用 RIGHT() 和 REPLICATE() 的组合
          这个方法和之前的方法几乎一样,唯一的区别是我只是用 REPLICATE() 函数替换了三个零:

          SELECT RIGHT(REPLICATE('0', 2) + '12', 4);

          结果:
          0012

          方法 3 - 使用 REPLACE() 和 STR() 的组合
          这种方法与之前的方法完全不同的角度:

          SELECT REPLACE(STR('12', 4),' ','0');

          结果:
          0012

          查看文章,有更深入的示例分析。

          【讨论】:

            【解决方案10】:

            我创建了一个函数来执行此操作,您可以在其中指定所需的输出字符长度:

            CREATE FUNCTION [dbo].[udfLeadingZero]
            (
                    @String VARCHAR(MAX)
            ,       @Len INT
            )
            RETURNS VARCHAR(MAX)
            BEGIN
                SET @String = RIGHT(REPLICATE('0',@Len)+@String,@Len)
            RETURN @String
            END
            GO
            

            Example results

            【讨论】:

              【解决方案11】:

              我在 SQL 服务器上的一个函数中需要这个,并稍微调整了帕特里克的答案。

              declare @dossierId int = 123
              declare @padded_id varchar(7)
              
              
              set @padded_id = REPLACE(
                            SPACE(7 - LEN(@dossierId)) + convert(varchar(7), @dossierId), 
                            SPACE(1),  
                            '0') 
              
              SELECT @dossierId as '@dossierId'
                    ,SPACE(LEN(@dossierId)) + convert(varchar(7)
                    ,@dossierId) as withSpaces
                    ,@padded_id as '@padded_id'
              

              【讨论】:

                【解决方案12】:

                创建函数:

                    Create FUNCTION [dbo].[PadLeft]
                      (
                        @Text NVARCHAR(MAX) ,
                        @Replace NVARCHAR(MAX) ,
                        @Len INT
                      )
                RETURNS NVARCHAR(MAX)
                AS
                    BEGIN 
                
                
                        DECLARE @var NVARCHAR(MAX) 
                
                        SELECT @var = ISNULL(LTRIM(RTRIM(@Text)) , '')
                
                
                        RETURN   RIGHT(REPLICATE(@Replace,@Len)+ @var, @Len)
                
                
                    END
                

                例子:

                Select dbo.PadLeft('123456','0',8)
                

                【讨论】:

                • 只是关于标准的一点,我不会打扰 IsNull 检查,如果值为 null 则函数仍应为该值返回 null,因为这是内置函数的标准行为。如果我们将所有内容都转换为非空值,那么调用者将不再能够使用他们可能期望的空逻辑操作。 (我的许多表中的 Null 表示“未指定”,应使用默认值。SELECT @var = LTRIM(RTRIM(@Text))
                【解决方案13】:

                我创建了一个函数:

                CREATE FUNCTION [dbo].[fnPadLeft](@int int, @Length tinyint)
                RETURNS varchar(255) 
                AS 
                BEGIN
                    DECLARE @strInt varchar(255)
                
                    SET @strInt = CAST(@int as varchar(255))
                    RETURN (REPLICATE('0', (@Length - LEN(@strInt))) + @strInt);
                END;
                

                使用:select dbo.fnPadLeft(123, 10)

                返回:0000000123

                【讨论】:

                  【解决方案14】:

                  如果需要,一些相当符合 ODBC 的东西可能如下:

                  select ifnull(repeat('0', 5 - (floor(log10(FIELD_NAME)) + 1)), '')
                          + cast (FIELD as varchar(10))
                    from TABLE_NAME
                  

                  这是基于这样一个事实,即基数为 10 的数字的位数可以通过其日志的积分部分找到。从中我们可以从所需的填充宽度中减去它。对于小于 1 的值,重复将返回 null,因此我们需要 ifnull。

                  【讨论】:

                    【解决方案15】:

                    我的解决方案效率不高,但在值(银行支票号码和电汇参考号)存储为 varchar 的情况下帮助了我,其中一些条目带有字母数字值,如果长度小于我必须填充6 个字符。

                    如果有人遇到同样的情况,想分享一下

                    declare @minlen int = 6
                    declare @str varchar(20)
                    
                    set @str = '123'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: 000123
                    
                    set @str = '1234'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: 001234
                    
                    set @str = '123456'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: 123456
                    
                    set @str = '123456789'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: 123456789
                    
                    set @str = '123456789'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: 123456789
                    
                    
                    set @str = 'NEFT 123456789'
                    select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
                    --Ans: NEFT 123456789
                    

                    【讨论】:

                      【解决方案16】:

                      一个简单的例子是

                          DECLARE @number INTEGER
                          DECLARE @length INTEGER
                          DECLARE @char   NVARCHAR(10)
                          SET @number = 1
                          SET @length = 5
                          SET @char = '0'
                      
                          SELECT FORMAT(@number, replicate(@char, @length))
                      

                      【讨论】:

                        【解决方案17】:

                        更有效的方法是:

                        Select id, LEN(id)
                        From TableA
                        Order by 2,1 
                        
                        The result :
                        id
                        ----
                        1
                        2
                        12
                        123
                        1234
                        

                        【讨论】:

                        • 这如何回答 OP 关于用零填充的问题?
                        猜你喜欢
                        • 2010-12-24
                        • 2011-10-22
                        • 2012-09-14
                        • 1970-01-01
                        • 2010-09-09
                        • 2012-11-15
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多