Sql server 将字符串拆分为单独的行
我目前正在研究如何在“/”的每个实例中将ID拆分为两行。原始ID仍将保存在主表和临时表2中,但我需要将新ID保存到新表中。在生成报告之前,所有这些都发生在导入前处理程序上的临时表中 表输出当前如下所示:Sql server 将字符串拆分为单独的行,sql-server,Sql Server,我目前正在研究如何在“/”的每个实例中将ID拆分为两行。原始ID仍将保存在主表和临时表2中,但我需要将新ID保存到新表中。在生成报告之前,所有这些都发生在导入前处理程序上的临时表中 表输出当前如下所示: RWID RWLEN DESCR QTY UNIT T2/10060 20.0000 SomeInfo 1 pcs T2/10061 18.5689 SomeInfo 1 pcs T2/10062 20.0000 SomeI
RWID RWLEN DESCR QTY UNIT
T2/10060 20.0000 SomeInfo 1 pcs
T2/10061 18.5689 SomeInfo 1 pcs
T2/10062 20.0000 SomeInfo 1 pcs
我需要这张表来说明以下内容:
RWID RWLEN DESCR QTY UNIT
T10060 20.0000 SomeInfo 1 pcs
T20060 20.0000 SomeInfo 1 pcs
T10061 18.5689 SomeInfo 1 pcs
T20061 18.5689 SomeInfo 1 pcs
T10062 20.0000 SomeInfo 1 pcs
T20062 20.0000 SomeInfo 1 pcs
下面是我的代码片段:
-- populate temp table 1 from main table
SELECT *
INTO ##tmp1
FROM main;
-- populate temp table 2 from temp table 1, group and order by RWID
SELECT RWID, MAX(DESCR) as aux
INTO ##tmp2
FROM ##tmp1
group by RWID
ORDER by RWID;
-- populate temp table 3 from temp table 1 then split strings with dividers
SELECT RWID, RWLEN, DESCR, QTY, UNIT
INTO ##tmp3
FROM ##tmp1
UNION ALL
SELECT RWID, NULL RWLEN, NULL DESCR, NULL QTY, NULL UNIT
FROM ##tmp1
GROUP BY RWID
ORDER BY RWID, DESCR desc;
SELECT
RWID = CASE WHEN a.DESCR = b.AUX THEN a.RWID ELSE NULL END,
RWLEN = CASE WHEN a.DESCR = b.AUX THEN a.RWLEN ELSE NULL END,
a.DESCR,
a.QTY,
a.UNIT
INTO ##report
FROM ##tmp3
a
FULL OUTER JOIN ##tmp2
b on a.RWID = b.RWID;
SELECT *
FROM ##report
提前感谢您的时间和帮助
更新!非常感谢你的帮助,这真的把我引向了正确的方向。我已经找到了如何分割上面显示的字符串以及我将遇到的其他类型的ID,这些ID我没有包含在示例中。再次感谢你们的时间和帮助,你们都很棒
结果:使用CTE的SQL server
declare @table table (rwid varchar(30), rwlen float, descr varchar(50), qty int, unit varchar(4))
insert into @table
values
('T2/10060', 20.0000 ,'SomeInfo', 1 ,'pcs'),
('T2/10061', 18.5689 ,'SomeInfo', 1 ,'pcs'),
('T2/10062', 20.0000 ,'SomeInfo', 1 ,'pcs')
;with mycte as (
select *, cast(right(left(rwid,charindex('/',rwid)-1),1) as int) [num], 1 [start] from @table
union all
select t.*,c.start + 1, c.num from @table t
inner join mycte c
on c.rwid = t.rwid
and c.start + 1 <= c.num
)
select
concat(left(rwid,1), start,replace(rwid,left(rwid,charindex('/',rwid)+1),'')) ,
rwlen,
descr,
qty,
unit
from mycte
order by rwid, start
您可以简单地使用如下所示的联合来获得所需的输出
SELECT 'T1'+ SUBSTRING(RWID,CHARINDEX('/',RWID)+1,
LEN(RWID)- CHARINDEX('/',RWID)) -- + OTHER COLUMN
FROM [TABLE_NAME]
UNION ALL
SELECT 'T2'+ SUBSTRING(RWID,CHARINDEX('/',RWID)+1,
LEN(RWID)- CHARINDEX('/',RWID)) -- + OTHER COLUMN
FROM [TABLE_NAME]
完整示例
输出
使用交叉应用
;WITH CTE( RWID, RWLEN,DESCR,QTY, UNIT)
AS
(
SELECT 'T2/10060',20.0000,'SomeInfo', 1,'pcs' UNION ALL
SELECT 'T2/10061',18.5689,'SomeInfo', 1,'pcs' UNION ALL
SELECT 'T2/10062',20.0000,'SomeInfo', 1,'pcs'
)
SELECT REPLACE(RWID,'2/1',CAST(Rnk AS VARCHAr(2))) AS RWID
,RWLEN
,DESCR
,QTY
,UNIT
FROM
(
SELECT C.*,ROW_NUMBER()OVER(PARTITION BY C.RWID ORDER BY C.RWID) AS Rnk
FROM CTE C
CROSS APPLY CTE C2
)dt WHERE Rnk<3
结果
这是针对mysql还是sql server的?如果RWID不是以T开头呢?如果是这样,我们可以使用子字符串而不是硬编码来获取第一个字符
+---------+-------+----------+-----+------+
| RWID | RWLEN | DESCR | QTY | UNIT |
+---------+-------+----------+-----+------+
| T110060 | 20.00 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
| T110061 | 18.57 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
| T110062 | 20.00 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
| T210060 | 20.00 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
| T210061 | 18.57 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
| T210062 | 20.00 | SomeInfo | 1 | pcs |
+---------+-------+----------+-----+------+
;WITH CTE( RWID, RWLEN,DESCR,QTY, UNIT)
AS
(
SELECT 'T2/10060',20.0000,'SomeInfo', 1,'pcs' UNION ALL
SELECT 'T2/10061',18.5689,'SomeInfo', 1,'pcs' UNION ALL
SELECT 'T2/10062',20.0000,'SomeInfo', 1,'pcs'
)
SELECT REPLACE(RWID,'2/1',CAST(Rnk AS VARCHAr(2))) AS RWID
,RWLEN
,DESCR
,QTY
,UNIT
FROM
(
SELECT C.*,ROW_NUMBER()OVER(PARTITION BY C.RWID ORDER BY C.RWID) AS Rnk
FROM CTE C
CROSS APPLY CTE C2
)dt WHERE Rnk<3