【问题标题】:Appending charactes to a string when duplicate found发现重复时将字符附加到字符串
【发布时间】:2015-07-25 14:57:45
【问题描述】:

假设我有一个 ID、名称和一个字段来标记更新,如下所示:

+----+-------+---------+
| ID | Name  | Update? |
+----+-------+---------+
|  1 | A     | y       |
|  2 | B     | y       |
|  3 | xxB   |         |
|  4 | C     |         |
|  5 | D     | y       |
|  6 | xxD   |         |
|  7 | xxxD  |         |
|  8 | E     |         |
+----+-------+---------+

“更新”是在名称后附加一个“xx”,但是表中不能有重复的名称,所以我想在找到的任何重复项上附加一个额外的“x”。所以对于这个,表格将更新为:

+----+-------+---------+
| ID | Name  | Update? |
+----+-------+---------+
|  1 | xxA   |         |
|  2 | xxB   |         |
|  3 | xxxB  |         |
|  4 | C     |         |
|  5 | xxD   |         |
|  6 | xxxD  |         |
|  7 | xxxxD |         |
|  8 | E     |         |
+----+-------+---------+

关于最佳方式的任何想法?它更新了我坚持的初始更新时会发生的重复项,我不确定让它重新检查并更新所有重复级别有多容易,例如 A 不是重复的, B是1级,D是2级等。

谢谢, 戴夫

【问题讨论】:

  • 当你想要 A 到 XXA 然后 E 也 XXE 时你想要什么 ..但你提到了 E

标签: sql-server sql-server-2012 duplicates


【解决方案1】:

试试这个:

SQL Fiddle

WITH CteUpdate AS(
    SELECT *, 
        base = REPLACE(Name, 'x', ''),
        xxName = REPLICATE('x', 
                    ROW_NUMBER() OVER(
                        PARTITION BY REPLACE(Name, 'x', '') 
                        ORDER BY ID
                    ) + 1
                ) + REPLACE(Name, 'x', '')
    FROM TestData
    WHERE
        REPLACE(Name, 'x', '') IN(
            SELECT Name FROM TestData WHERE [Update] = 1
        )
)
UPDATE CteUpdate 
    SET Name = xxName
        , [Update] = 0

结果

ID          Name       Update
----------- ---------- ------
1           xxA        0
2           xxB        0
3           xxxB       0
4           C          0
5           xxD        0
6           xxxD       0
7           xxxxD      0
8           E          0

首先,您希望获取具有相同基数 NameName 减去 xxs)的所有行以及具有 Update = 1 的行。要获取基础Name,只需将x 替换为''

SELECT *, 
    base = REPLACE(Name, 'x', '')
FROM TestData
WHERE
    REPLACE(Name, 'x', '') IN(
        SELECT Name FROM TestData WHERE [Update] = 1
    )

上面的结果将是:

ID          Name       Update base
----------- ---------- ------ ------
1           A          1      A
2           B          1      B
3           xxB        0      B
5           D          1      D
6           xxD        0      D
7           xxxD       0      D

然后,您想使用ROW_NUMBER OVER(PARTITION BY base ORDER BY ID)。生成的 ROW_NUMBER + 1 将是要添加到 base 上的 xs 的数量

WITH CteUpdate AS(
    SELECT *, 
        base = CAST(REPLACE(Name, 'x', '') AS VARCHAR(1))
    FROM TestData
    WHERE
        REPLACE(Name, 'x', '') IN(
            SELECT Name FROM TestData WHERE [Update] = 1
        )
)
SELECT
    RN = ROW_NUMBER() OVER(PARTITION BY base ORDER BY ID),
    xxName = REPLICATE('x', ROW_NUMBER() OVER(PARTITION BY base ORDER BY ID) + 1) + base
FROM CteUpdate

上面的查询结果将是:

ID          Name       Update base   RN    xxName
----------- ---------- ------ ------ ----- ---------
1           A          1      A      1     xxA
2           B          1      B      1     xxB
3           xxB        0      B      2     xxxB
5           D          1      D      1     xxD
6           xxD        0      D      2     xxxD
7           xxxD       0      D      3     xxxxD

xxName 现在将更新为 Name

【讨论】:

  • 感谢您的精彩解释!我试试看。
  • 没问题。欢迎提出任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 2012-05-28
  • 2012-10-04
相关资源
最近更新 更多