我有一张桌子,必须有下一个结构:
╔════╦═══════╦════╦═════╗ ║ id ║ a ║ c ║ b ║ ╠════╬═══════╬════╬═════╣ ║ 55 ║ 56;57 ║ ║ P25 ║ ║ 56 ║ ║ 56 ║ 25 ║ ║ 57 ║ ║ 57 ║ 25 ║ ╚════╩═══════╩════╩═════╝
其中:
1)id = 55的记录是 父记录 和
2)id = 56,id = 57的记录(列在 a 列中并用分号分隔)
是 子记录 < / p>
第一个表是下一个
╔════╦═══════╦════╦═════╗ ║ id ║ a ║ c ║ b ║ ╠════╬═══════╬════╬═════╣ ║ 55 ║ 56;57 ║ ║ ║ ║ 56 ║ ║ 56 ║ ║ ║ 57 ║ ║ 57 ║ ║ ╚════╩═══════╩════╩═════╝
所以我必须更新第一张表
等表格为此我创建了下一个CTE
with My_CTE(PId, a, c, b, newC, inde) as
(
select
ST.PID, ST.a, ST.c, ST.b, res.C,
ind = case
when ST.a != ''
then (dense_rank() over(order by ST.a))
end
from STable as ST
outer APPLY
fnSplit(ST.a) as res
where (not(ST.a = '') or not(ST.c = ''))
)
UPDATE STable
Set b =
cte.inde
From STable as st
Join My_CTE as cte on st.PID = cte.PId;
GO
结果我有下一个值的表
╔════╦═══════╦════╦═════╗ ║ id ║ a ║ c ║ b ║ ╠════╬═══════╬════╬═════╣ ║ 55 ║ 56;57 ║ ║ 25 ║ ║ 56 ║ ║ 56 ║ ║ ║ 57 ║ ║ 57 ║ ║ ╚════╩═══════╩════╩═════╝
所以我需要在子列 b 中为子记录设置值。
也许它可以在MyCTE的精选声明中建立?
请帮忙
答案 0 :(得分:0)
我不完全确定我是否理解你的要求,如果我误解了,请道歉。
所以你已经设法将结果集设置到这里
╔════╦═══════╦════╦═════╗
║ id ║ a ║ c ║ b ║
╠════╬═══════╬════╬═════╣
║ 55 ║ 56;57 ║ ║ 25 ║
║ 56 ║ ║ 56 ║ ║
║ 57 ║ ║ 57 ║ ║
╚════╩═══════╩════╩═════╝
现在你希望它看起来像这样
╔════╦═══════╦════╦═════╗
║ id ║ a ║ c ║ b ║
╠════╬═══════╬════╬═════╣
║ 55 ║ 56;57 ║ ║ P25 ║
║ 56 ║ ║ 56 ║ 25 ║
║ 57 ║ ║ 57 ║ 25 ║
╚════╩═══════╩════╩═════╝
请查看此脚本是否适合您。
IF OBJECT_ID(N'tempdb..#temp')>0
DROP TABLE #temp
IF OBJECT_ID(N'tempdb..#temp1')>0
DROP TABLE #temp1
CREATE TABLE #temp (id int, a varchar(100),c varchar(100),b varchar(100))
INSERT INTO #temp VALUES ('55','56;57',' ','25')
INSERT INTO #temp VALUES ('56',' ','56',' ')
INSERT INTO #temp VALUES ('57',' ','57',' ')
SELECT * FROM #temp t
SELECT y.id, fn.string AS a,y.b
INTO #temp1
FROM #temp AS y
CROSS APPLY dbo.fnParseStringTSQL(y.a, ';') AS fn
--SELECT * FROM #temp1
UPDATE t
SET t.b=CASE WHEN CHARINDEX(';',t.a)>0 THEN 'P'+t.b ELSE t1.b END
FROM #temp t
LEFT JOIN #temp1 t1
ON t.id = t1.a
--DROP TABLE #temp
SELECT * FROM #temp t
IF OBJECT_ID(N'tempdb..#temp')>0
DROP TABLE #temp
IF OBJECT_ID(N'tempdb..#temp1')>0
DROP TABLE #temp1
借用此link
的函数CREATE FUNCTION [dbo].[fnParseStringTSQL]
(
@string NVARCHAR(MAX),
@separator NCHAR(1)
)
RETURNS @parsedString TABLE (string NVARCHAR(MAX))
AS
BEGIN
DECLARE @position INT
SET @position = 1
SET @string = @string + @separator
WHILE CHARINDEX(@separator, @string, @position) <> 0
BEGIN
INSERT INTO @parsedString
SELECT SUBSTRING(
@string,
@position,
CHARINDEX(@separator, @string, @position) - @position
)
SET @position = CHARINDEX(@separator, @string, @position) + 1
END
RETURN
END
答案 1 :(得分:0)
这实际上不是一个理想的数据结构,但以下内容将会这样做......
CREATE TABLE #STable
(
id int primary key clustered
, a varchar(500)
, c varchar(500)
, b varchar(500)
)
INSERT INTO #STable
(id, a, c, b)
VALUES (55, '56;57', '', '25')
, (56, '', '56', '')
, (57, '', '57', '')
/* >>>>> Get all parents <<<<< */
CREATE TABLE #folks
(
sno int identity(1,1)
, id int
, a varchar(500)
)
CREATE TABLE #family
(
parent int
, child int
)
INSERT INTO #folks
(id, a)
SELECT id, a
FROM #STable
WHERE a <> ''
DECLARE @NID int
, @XID int
, @parent int
, @Children varchar(500)
, @Child int
SELECT @NID = MIN(sno), @XID = MAX(sno)
FROM #folks
/* >>>>> Loop to figure out the children <<<<< */
WHILE @NID <= @XID
BEGIN
SELECT @parent = id, @Children = a
FROM #folks
WHERE sno = @NID
WHILE LEN(@Children) > 0
BEGIN
IF CHARINDEX(';', @Children) > 0
BEGIN
SET @Child = CAST(LEFT(@Children, CHARINDEX(';', @Children) -1) as int)
SET @Children = RIGHT(@Children, LEN(@Children) - CHARINDEX(';', @Children))
INSERT INTO #family
(parent, child)
VALUES (@parent, @Child)
END
ELSE
BEGIN
SET @Child = CAST(@Children AS INT)
SET @Children = ''
INSERT INTO #family
(parent, child)
VALUES (@parent, @Child)
END
END
SET @NID = @NID + 1
END
/* >>>>> Update <<<<< */
UPDATE c
SET b = p.b
FROM #family f
INNER JOIN #STable p
on f.parent = p.id
INNER JOIN #STable c
on f.child = c.id
SELECT *
FROM #STable
DROP TABLE #STable
DROP TABLE #folks
DROP TABLE #family