MSSQL:使用缺少的零来均衡计数值

时间:2015-06-11 12:31:04

标签: sql-server sql-server-2012

我使用CRM软件,几年前已从其他程序中导入了数千名客户。

现在我注意到我在导入时错过了一个字段中的零位数,导致新添加的地址出现在列表的最后,当它们应该是第一个时。 为了可视化问题,这里是(缩短的)架构:

CREATE TABLE ADDRESS
    ([customerid] varchar(20), [addressno] varchar(20), [name] varchar(50));

INSERT INTO ADDRESS
    ([customerid], [addressno], [name])
VALUES
    ('5705', '5705-01', 'John Doe'),
    ('5705', '5705-001', 'Jane Doe'),
    ('5705', '5705-002', 'Smith'),
    ('5705', '5705-003', 'Alice'),
    ('5706', '5706-01', 'Bob'),
    ('5707', '5707-001', 'Carol'),
    ('5707', '5707-002', 'Chuck')
;

如您所见,某些addressno值只有2位数(+" customerid - ") - 这些是导入的,新的有3位数。

我需要完成的是添加缺失的零,如果存在customerid的更多条目,它们的值应该增加,所以目标就是这个结果:

    ('5705', '5705-001', 'John Doe'),  /* Added a zero */
    ('5705', '5705-002', 'Jane Doe'),  /* Increased number */
    ('5705', '5705-003', 'Smith'),     /* Increased number */
    ('5705', '5705-004', 'Alice'),     /* Increased number */
    ('5706', '5706-001', 'Bob'),       /* Added a zero */
    ('5707', '5707-001', 'Carol'),     /* No change */
    ('5707', '5707-002', 'Chuck')      /* No change */

这在Microsoft SQL Server 2012上运行。我想在SQL中编写一个解决方案,这样我就可以在SQL Management Studio中运行它,这似乎是最简单的方法。

可悲的是,我的SQL知识非常基础,我真的不知道从哪里开始,所以感谢任何帮助。

4 个答案:

答案 0 :(得分:3)

这似乎做你想要的。我假设您显示的字符长度是固定的,从addressno重新导出customerid的左侧是安全的:<\ n / p>

declare @ADDRESS table
    ([customerid] varchar(20), [addressno] varchar(20), [name] varchar(50));

INSERT INTO @ADDRESS
    ([customerid], [addressno], [name])
VALUES
    ('5705', '5705-01', 'John Doe'),
    ('5705', '5705-001', 'Jane Doe'),
    ('5705', '5705-002', 'Smith'),
    ('5705', '5705-003', 'Alice'),
    ('5706', '5706-01', 'Bob'),
    ('5707', '5707-001', 'Carol'),
    ('5707', '5707-002', 'Chuck')

; With Extracts as (
    select *,
        CONVERT(int,SUBSTRING(addressno,6,3)) as rn,
        CASE WHEN LEN(addressno)=7 THEN 0 ELSE 1 END as series
    from
        @ADDRESS
), newnumbers as (
    select *,ROW_NUMBER() OVER (PARTITION BY customerid ORDER BY series,rn) as row
    from Extracts
)
update newnumbers
set addressno =
    customerid + '-' +
    RIGHT('000'+CONVERT(varchar(20),row),3)

select * from @ADDRESS

结果:

customerid           addressno            name
-------------------- -------------------- ------------
5705                 5705-001             John Doe
5705                 5705-002             Jane Doe
5705                 5705-003             Smith
5705                 5705-004             Alice
5706                 5706-001             Bob
5707                 5707-001             Carol
5707                 5707-002             Chuck

答案 1 :(得分:0)

您可以执行以下操作:

WITH    cte
          AS ( SELECT   * ,
                        CAST(ROW_NUMBER() OVER ( PARTITION BY customerid ORDER BY name ) AS VARCHAR(20)) AS rn
               FROM     dbo.ADDRESS
             )
UPDATE cte SET addressno = CAST(customerid AS VARCHAR(20)) + '-' + 
                           REPLICATE('0', 3 - LEN(rn)) + rn

您可能希望将( PARTITION BY customerid ORDER BY name )

替换为( PARTITION BY customerid ORDER BY AddressID )

答案 2 :(得分:0)

这是一个更简单的解决方案。

<Questions>
    <id>1</id>
    <question>
    This is question 1.
    </question>
</Questions>
<Questions>
    <id>3</id>
    <question>
    This is question 3.
    </question>
</Questions>

只是更新是必要的部分。

答案 3 :(得分:0)

DECLARE  @ADDRESS TABLE
    ([customerid] varchar(20), [addressno] varchar(20), [name] varchar(50));

INSERT INTO @ADDRESS
    ([customerid], [addressno], [name])
VALUES
    ('5705', '5705-01', 'John Doe'),
    ('5705', '5705-001', 'Jane Doe'),
    ('5705', '5705-002', 'Smith'),
    ('5705', '5705-003', 'Alice'),
    ('5706', '5706-01', 'Bob'),
    ('5707', '5707-001', 'Carol'),
    ('5707', '5707-002', 'Chuck')

;

select [customerid], SUBSTRING([addressno],0,CHARINDEX('-',[addressno]))+ 
'-' 
+RIGHT('00000'+ CONVERT(VARCHAR,REVERSE(SUBSTRING(REVERSE([addressno]),0,CHARINDEX('-',REVERSE([addressno]))))),3), 
[name] from @ADDRESS