[英]How to split the data in a single row into multiple rows in SQL?
I have a table in the following format我有以下格式的表格
ProjectID LocationID
1 [1,2,3,4]
2 [2,3]
Can I split the data in the column LocationID into multiple rows like below?我可以将 LocationID 列中的数据拆分为如下所示的多行吗?
ProjectID LocationID
1 1
1 2
1 3
1 4
2 2
2 3
I need to get the data loaded to Power-Bi using the SQL only.我只需要使用 SQL 将数据加载到 Power-Bi。 is it possible?
可能吗?
If data type of locationID is varchar then:如果 locationID 的数据类型是 varchar 则:
create table projects (ProjectID int, LocationID varchar(50));
insert into projects values(1, '[1,2,3,4]');
insert into projects values(2, '[2,3]');
Query:询问:
select projectid, value
from projects
CROSS APPLY STRING_SPLIT(replace(replace(locationid,'[',''),']',''),',')
Output: Output:
projectid![]() |
value![]() |
---|---|
1 ![]() |
1 ![]() |
1 ![]() |
2 ![]() |
1 ![]() |
3 ![]() |
1 ![]() |
4 ![]() |
2 ![]() |
2 ![]() |
2 ![]() |
3 ![]() |
Solution for SQL Server 2014 SQL 服务器解决方案 2014
create table projects (ProjectID int, LocationID nvarchar(max));
insert into projects values(1, '[1,2,3,4]');
insert into projects values(2, '[2,3]');
Query:询问:
WITH tmp AS
(
SELECT
ProjectID,
LEFT(replace(replace(locationid,'[',''),']',''), CHARINDEX(',', replace(replace(locationid,'[',''),']','') + ',') - 1) LocationID,
STUFF(replace(replace(locationid,'[',''),']',''), 1, CHARINDEX(',', replace(replace(locationid,'[',''),']','') + ','), '') b
FROM projects
UNION all
SELECT
ProjectID,
LEFT(b, CHARINDEX(',', b + ',') - 1),
STUFF(b, 1, CHARINDEX(',', b + ','), '')
FROM tmp
WHERE
b > ''
)
SELECT
ProjectID, LocationID
FROM tmp
ORDER BY projectid
Output: Output:
ProjectID![]() |
LocationID![]() |
---|---|
1 ![]() |
1 ![]() |
1 ![]() |
2 ![]() |
1 ![]() |
3 ![]() |
1 ![]() |
4 ![]() |
2 ![]() |
2 ![]() |
2 ![]() |
3 ![]() |
In SQL Server 2014, you can use a recursive CTE -- which Kazi also proposes.在 SQL Server 2014 中,您可以使用递归 CTE——Kazi 也提出了这一点。 I think this is a slightly simpler version:
我认为这是一个稍微简单的版本:
with cte as (
select projectId, convert(varchar(max), null) as locationid,
convert(varchar(max), substring(LocationId, 2, len(locationId) - 2)) + ',' as rest
from t
union all
select projectId,
left(rest, charindex(',', rest) - 1),
stuff(rest, 1, charindex(',', rest), '')
from cte
where rest <> ''
)
select projectid, locationid
from cte
where locationid is not null;
Here is a db<>fiddle. 这是一个 db<>fiddle。
In particular, the anchor part just sets up the data -- it does not extract any elements from the string.特别是,锚部分只是设置数据——它不从字符串中提取任何元素。 So, all the logic is in the recursive part, which I find easier to maintain.
所以,所有的逻辑都在递归部分,我发现它更容易维护。
I used STRING_SPLIT() which is a table valued function supports SQL server 2016 and higher versions.我使用了 STRING_SPLIT() 这是一个表值 function 支持 SQL 服务器 2016 和更高版本。 You need to provide the formatted string into this function and use cross apply to join and generate the desired output.
您需要在此 function 中提供格式化字符串,并使用交叉应用来连接并生成所需的 output。
SELECT
projectID
, REPLACE(REPLACE(locationId,'[',''),']','') as [locationid]
INTO #temp_table
FROM split_string -- Add your table name here
SELECT
projectID
,VALUE [locationid]
FROM #temp_table
CROSS APPLY STRING_SPLIT( [locationid] , ',');
Thanks everyone for helping me out.感谢大家帮助我。 This solution works for my scenario.
此解决方案适用于我的场景。
Select projectID,locationid_list from project CROSS APPLY OPENJSON(locationid, '$') WITH (locationid_list int '$') Select projectID,locationid_list from project CROSS APPLY OPENJSON(locationid, '$') WITH (locationid_list int '$')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.