删除特殊字符分隔字符串中的重复项和 NULL

Removing duplicates and NULL in Special character separated String

在开始我的问题之前,我肯定同意这是一个糟糕的设计,现在我们正在努力修复它。展望未来,对于所有新数据,我们将遵循 1NF

---Here is the fiddle----

我有一个这样的table数据。

我想删除重复的值和 'NULL' 个值。

预期输出:

180;;200
AMD;;SRD
ASE;;GIF;;TED
1
AMD;;SRD
null
LKG;;This is text with space

我试过的:

WITH Splitted AS
(

    select id,attr,val
     ,CAST('<x>' + REPLACE(replace(val,'NULL',''),';;','</x><x>') + '</x>' AS XML) AS TheParts
    from test where val like '%;;%' 
)
SELECT 
      Replace(STUFF(
          (TheParts.query
          ('
          for $x in distinct-values(/x/text())
            return <x>{concat(";;", $x)}</x>
          ').value('.','varchar(250)')),1,2,''),' ','') AS ColumnB
FROM Splitted;

当前输出

180;;200
AMD;;SRD
ASE;;GIF;;TED;;ASE  --problem here
1
AMD;;SRD
null
LKG;;Thisistextwithspace -- problem here

我也在字符串之间丢失 space。在某些情况下,该值会重复。我想是因为最后有额外的 spaces。如何解决这个问题?或者有没有更好的方法来实现这个?

由于您使用的是旧版本的 SQL 服务器,因此您无法访问 STRING_SPLITSTRING_AGG。然而,前者在这里并不是特别有用,因为 Microsoft still 还没有在函数中实现序数位置,它只支持单个字符分离器.

我将改用 DelimitedSplit8k_LEAD 支持序数位置。不幸的是,它也只支持单个字符分隔符,所以我用竖线 (|) 替换了双分号 (;;) 分隔符;因为我认为这不会出现在您的数据中。

2012 也没有 TRIM,因此您需要使用 RTRIMLTRIM 来 trim 值。

最后可以使用"old"FOR XML PATH方法"re-aggregate"字符串:

WITH Splits AS(
    SELECT t.id,
           t.attr,
           DS.ItemNumber,
           NULLIF(LTRIM(RTRIM(DS.Item)),'NULL') AS Item,
           ROW_NUMBER() OVER (PARTITION BY T.id, LTRIM(RTRIM(NULLIF(DS.Item,'NULL'))) ORDER BY DS.ItemNumber) AS RN
    FROM dbo.test t
         CROSS APPLY dbo.DelimitedSplit8K_LEAD(REPLACE(t.val,';;','|'),'|') DS) --DelimitedSplit8K only supports a one character splitter
SELECT t.ID,
       t.attr,
       STUFF((SELECT ';;' + S.Item
              FROM Splits S
              WHERE S.ID = t.ID
                AND S.RN = 1
              ORDER BY S.ItemNumber
              FOR XML PATH(''),TYPE).value('.','varchar(MAX)'),1,2,'') AS NewVal
FROM dbo.test t;

编辑:忘记了重复项。我在 CTE 中使用 ROW_NUMBER 对值进行编号,然后在 FOR XML PATH 子查询的 WHERE 中进行过滤。 DISTINCTGROUP BY 不会在那里工作,因为 ItemNumber 将不允许在 ORDER BY.

中使用