2017-05-09 35 views
1

アルファベットと数字のテキストブロックの間にハイフンを挿入する必要があります。 私はこの問題をどのように開始するかについてもわかりません。アルファベットと数字の間にハイフンを挿入する方法

ABC123 -> ABC-123 
ABC123XYZ -> ABC-123-XYZ 
D123 -> D-123 
123C -> 123-C 
+0

なぜo.Oはdownvotes? –

+0

これらの列の値は1つまたは複数のテーブルにありますか? – artm

+0

@ShakeerMirza。おそらく、多くの理由で、1)OPは、これを修正するために彼が今行ったことを示さなかった、2)SOサイトは生成されたコードツールではない、おそらく他の理由。 (私はダウン者ではありません) –

答えて

4

これは単一の値で動作します。

DECLARE @CODE VARCHAR(50) = '12ABC123XYZ' 
    ,@NEWCODE VARCHAR(100) = '' 

;WITH CTE 
AS (
    SELECT NUMBER 
     ,SUBSTRING(@CODE, NUMBER, 1) AS VAL 
    FROM master.dbo.spt_values 
    WHERE TYPE = 'P' 
     AND number BETWEEN 1 
      AND LEN(@CODE) 
    ) 
SELECT @NEWCODE = @NEWCODE + CASE 
     WHEN ISNUMERIC(C1.VAL) <> ISNUMERIC(ISNULL(C2.VAL, C1.VAL)) 
      THEN '-' + C1.VAL 
     ELSE C1.VAL 
     END 
FROM CTE C1 
LEFT JOIN CTE C2 ON C1.number = C2.number + 1 

SELECT @NEWCODE 

結果: 12-ABC-123-XYZ

そして、あなたは、これはテーブルのカラムで作業する場合は、スカラー関数を作成する必要があります。

CREATE FUNCTION CODE_SPLIT 
(

    @CODE VARCHAR(50) 
) 
RETURNS VARCHAR(100) 
AS 
BEGIN 

    DECLARE @NEWCODE VARCHAR(100) =''; 

    ;WITH CTE 
    AS (
     SELECT NUMBER 
      ,SUBSTRING(@CODE, NUMBER, 1) AS VAL 
     FROM master.dbo.spt_values 
     WHERE TYPE = 'P' 
      AND number BETWEEN 1 
       AND LEN(@CODE) 
     ) 
    SELECT @NEWCODE = @NEWCODE + CASE 
      WHEN ISNUMERIC(C1.VAL) <> ISNUMERIC(ISNULL(C2.VAL, C1.VAL)) 
       THEN '-' + C1.VAL 
      ELSE C1.VAL 
      END 
    FROM CTE C1 
    LEFT JOIN CTE C2 ON C1.number = C2.number + 1 

    RETURN @NEWCODE 

END 
GO 

そして、あなたの実際のテーブルの上にそれを呼び出す

スキーマ:

SELECT * INTO #TAB FROM(
SELECT 'ABC123' AS CODE 
UNION ALL 
SELECT 'ABC123XYZ' 
UNION ALL 
SELECT 'D123' 
UNION ALL 
SELECT '123C' 
)A 

SELECT CODE, dbo.CODE_SPLIT(CODE) AS NEWCODE FROM #TAB 

結果:最初の数の

+-----------+-------------+ 
| CODE | NEWCODE | 
+-----------+-------------+ 
| ABC123 | ABC-123  | 
| ABC123XYZ | ABC-123-XYZ | 
| D123  | D-123  | 
| 123C  | 123-C  | 
+-----------+-------------+ 
+1

スーパーコードブローチ..率直に吹いています...あなたは魅惑的なコーディングスキルでこれまでずっとロックしています..私はこのすべてのものを紛失しています...本当に悲しいです(|: - –

+1

Mahesh.K –

1

patindex('%[0-9]%')リターン指数。
patindex('%[^0-9]%')最初の非数値文字のインデックスを返します。
このようにrecursive CTEPATINDEXを使用できます。

DECLARE @SampleData AS TABLE 
(
    TextValue varchar(100) 
) 
INSERT INTO @SampleData 
VALUES ('ABC124'), ('ABC123XYZ'), ('123C'), ('ABC'), ('1A2B3C') 

;WITH cte AS 
(
    SELECT sd.TextValue AS RootText, 
     sd.TextValue AS CurrentText, 
     CAST('' AS varchar(100)) AS Result 
    FROM @SampleData sd 

    UNION ALL 

     SELECT  
      c.RootText, 
      CASE  
        WHEN patindex('%[0-9]%', c.CurrentText) = 0 OR patindex('%[^0-9]%', c.CurrentText) = 0 
         THEN '' 
        WHEN patindex('%[0-9]%', c.CurrentText) > patindex('%[^0-9]%', c.CurrentText) 
         THEN RIGHT(c.CurrentText, len(c.CurrentText) - patindex('%[0-9]%', c.CurrentText) + 1) 
        ELSE RIGHT(c.CurrentText, len(c.CurrentText) - patindex('%[^0-9]%', c.CurrentText) + 1) 
      END AS CurrentText, 
      CAST(
        CASE 
         WHEN patindex('%[0-9]%', c.CurrentText) = 0 OR patindex('%[^0-9]%', c.CurrentText) = 0 
          THEN Result + '-' + c.CurrentText 
         WHEN patindex('%[0-9]%', c.CurrentText) > patindex('%[^0-9]%', c.CurrentText) 
          THEN Result + '-' + LEFT(CurrentText, patindex('%[0-9]%', c.CurrentText) - 1) 
         ELSE Result + '-' + LEFT(CurrentText, patindex('%[^0-9]%', c.CurrentText) - 1) 
        END AS varchar(100) 
       ) AS Result 
    FROM cte c 
    WHERE LEN(CurrentText) > 0 
) 
SELECT cte.RootText, STUFF(cte.Result, 1,1,'') AS Result FROM cte 
WHERE cte.CurrentText = '' 

デモへのリンク:http://rextester.com/FTYA72053

関連する問題