2017-04-19 85 views
0

如果在給定列中存在任何特定值(本例中爲'[#]'),我需要獲取3個相似的行數據集替換列值。例如根據列值將單行分割成更多列

--------------------- 
Type  Value 
--------------------- 
1  Apple[#] 
2  Orange 
3  Peach[#] 

我需要修改查詢來獲取值,如下

---------------------- 
    Type  Value 
-------------------- 
    1   Apple1 
    1   Apple2 
    1   Apple3 
    2   Orange 
    3   Peach1 
    3   Peach2 
    3   Peach3 

我不能想出邏輯如何得到這個

+0

如何你認識你嗎?想要3個蘋果和3個桃子,但只有1個桔子? – jarlh

+0

它基於列中存在的'#'符號。我忘了提及 –

+0

所以如果有[#],那麼你總是想要3,否則1? –

回答

1

您也可以不用遞歸性相同的結果:

select Type, Value from MyTable where Right(Value, 3) <> '[#]' 
union 
select Type, Replace(Value, '[#]', '1') from MyTable where Right(Value, 3) = '[#]' 
union 
select Type, Replace(Value, '[#]', '2') from MyTable where Right(Value, 3) = '[#]' 
union 
select Type, Replace(Value, '[#]', '3') from MyTable where Right(Value, 3) = '[#]' 

order by 1, 2 
+0

謝謝,這工作。這是一個非常簡單易懂的解決方案。 –

1

假設只存在一個數字(如在你的例子中),那麼我會去:

with cte as (
     select (case when value like '%\[%%' then left(right(value, 2), 1) + 0 
        else 1 
       end) as cnt, 1 as n, 
      left(value, charindex('[', value + '[')) as base, type 
     from t 
     union all 
     select cnt, n + 1, base, type 
     from cte 
     where n + 1 <= cnt 
    ) 
select type, 
     (case when cnt = 1 then base else concat(base, n) end) as value 
from cte; 

當然,CTE可以很容易地擴展到數字y個:

(case when value like '%\[%%' 
     then stuff(left(value, charindex(']')), 1, charindex(value, '['), '') + 0 
     else 1 
end) 

一旦你有多少,你可以使用數字的另一個來源。但遞歸CTE似乎是問題中特定問題的最簡單解決方案。

0

嘗試此查詢

DECLARE @SampleData AS TABLE 
(
    Type int, 
    Value varchar(100) 
) 

INSERT INTO @SampleData 
VALUES (1, 'Apple[#]'), (2, 'Orange'), (3, 'Peach[#]') 

SELECT sd.Type, cr.Value 
FROM @SampleData sd 
CROSS APPLY 
(
    SELECT TOP (IIF(Charindex('[#]', sd.Value) > 0, 3, 1)) 
      x.[Value] + Cast(v.t as nvarchar(5)) as Value 
    FROM 
     (SELECT Replace(sd.Value, '[#]', '') AS Value) x 
     Cross JOIN (VALUES (1),(2),(3)) v(t) 
    Order by v.t asc 

) cr 

演示鏈接:Rextester

0

使用遞歸CTE

CREATE TABLE #test 
(
    Type int, 
    Value varchar(50) 
) 

INSERT INTO #test VALUES 
(1, 'Apple[#]'), 
(2, 'Orange'), 
(3, 'Peach[#]'); 

WITH CTE AS (
    SELECT 
     Type, 
     IIF(RIGHT(Value, 3) = '[#]', LEFT(Value, LEN(Value) - 3), Value) AS 'Value', 
     IIF(RIGHT(Value, 3) = '[#]', 1, NULL) AS 'Counter' 
    FROM 
     #test 
    UNION ALL 
    SELECT 
     B.Type, 
     LEFT(B.Value, LEN(B.Value) - 3) AS 'Value', 
     Counter + 1 
    FROM 
     #test AS B 
     JOIN CTE 
      ON B.Type = CTE.Type 
    WHERE 
     RIGHT(B.Value, 3) = '[#]' 
     AND Counter < 3 
) 

SELECT 
    Type, 
    CONCAT(Value, Counter) AS 'Value' 
FROM 
    CTE 
ORDER BY 
    Type, 
    Value 

DROP TABLE #test