Sql 基于列值将单行拆分为更多列
在这种情况下,如果给定列“[]”中存在任何特定值,我需要获得3组类似的行数据来替换列值。比如说Sql 基于列值将单行拆分为更多列,sql,sql-server,database,tsql,Sql,Sql Server,Database,Tsql,在这种情况下,如果给定列“[]”中存在任何特定值,我需要获得3组类似的行数据来替换列值。比如说 --------------------- Type Value --------------------- 1 Apple[#] 2 Orange 3 Peach[#] 我需要修改查询以获得如下值 ---------------------- Type Value -------------------- 1
---------------------
Type Value
---------------------
1 Apple[#]
2 Orange
3 Peach[#]
我需要修改查询以获得如下值
----------------------
Type Value
--------------------
1 Apple1
1 Apple2
1 Apple3
2 Orange
3 Peach1
3 Peach2
3 Peach3
我想不出如何得到这个的逻辑,假设只有一个数字,如您的示例所示,那么我会选择:
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似乎是问题中特定问题的最简单解决方案。假设只有一个数字,如您的示例所示,那么我会选择:
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似乎是问题中特定问题的最简单解决方案。试试这个查询
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
演示链接:尝试此查询
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
演示链接:您也可以在不使用递归的情况下获得相同的结果:
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
您也可以在不使用递归的情况下获得相同的结果:
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
使用递归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
使用递归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
你怎么知道你想要3个苹果和3个桃子,但只想要1个橘子?这是基于列中的符号。我忘了提到这一点,所以如果有[],那么您总是想要3,否则是1?如果有[],我想要3行类似的列,使用select语句动态地将值从1追加到3。如果[]不存在,我希望能够得到相同的结果。你知道你想要3个苹果和3个桃子,但只想要1个橙色吗?它基于列中存在的符号。我忘了提到这一点,所以如果有[],那么您总是想要3,否则是1?如果有[],我想要3行类似的列,使用select语句动态地将值从1追加到3。如果[]不存在,我希望能够得到相同的结果谢谢,这很有效。这是一个非常简单易懂的解决方案。谢谢,这很有效。这是一个非常简单易懂的解决方案。