我有一个包含记录组的大表。 我需要更改内部组ID - 我想为每个组单独运行此过程
示例数据
Index Group InternalID Data
001 01 01
002 01 02
003 01 03 Split
004 01 04
005 02 01
006 02 02 Split
007 02 03
008 02 04
009 02 05
100 03 01
101 03 02
102 03 03
103 03 04 Split
104 03 05
对于每个小组,我需要执行以下操作:
最终结果应为
Group InternalID Data
01 05
01 06
01 07 Split
01 08 NewItem1
01 09 NewItem2
01 10
02 06
02 07 Split
02 08 NewItem1
02 09 newItem2
02 10
02 11
02 12
03 06
03 07
03 08
03 09 Split
03 10 NewItem1
03 11 NewItem2
03 12
我想它看起来像[当心伪代码!!!不是真正的SQL!]
Declare @GCount VARCHAR(10)
@GSplit VARCHAR(10)
CREATE TABLE ##temp (
Idx int,
Grp int,
InternalID int,
Data varchar (10)
FOREACH [Group] from [Example]
Select @GCount = COUNT(InternalID)
Select @GSplit = (select InternalID from [Example] where [Data]='Split')
Insert Into ##temp
Select Grp, Data,
CASE WHEN InternalID <= @GSplit THEN InternalID + @GCount
ELSE THEN InternalID+@GCount+2
END AS InternalID
INSERT INTO ##temp
VALUES (00,[Group],@GSplit + @GCount + 1, 'NewItem1'), (01,[Group],@GSplit + @GCount + 2, 'NewItem2')
END FOREACH
UPDATE
[Example]
SET
[Example].* = ##temp.*
FROM
##temp
OUTER JOIN
[Example]
ON
##temp.Idx=[Example].Idx
IF OBJECT_ID('tempdb..##temp') IS NOT NULL
BEGIN
Drop Table ##temp
END
)
我知道上面不存在,但我怎样才能获得相同的功能?
答案 0 :(得分:1)
使用Windows函数找出拆分的位置以及组的大小。
根据拆分行添加新行。这可以确保您知道要应用的ID,以及仅添加实际为拆分的行。
使用算术和CASE
计算出正确的id值。
WITH
summarised AS
(
SELECT
*,
MAX([InternalID])
OVER (PARTITION BY [group]) AS GroupMaxID,
MAX(CASE WHEN [data] = 'split' THEN [InternalID] END)
OVER (PARTITION BY [group]) AS GroupSplitID
FROM
yourData
)
SELECT
[group],
GroupMaxID
+ InternalID
+ CASE WHEN InternalID > GroupSplitID THEN 2 ELSE 0 END AS InternalID,
[data]
FROM
summarised
UNION ALL
SELECT
summarised.[group],
summarised.GroupMaxID
+ summarised.InternalID
+ NewRows.Offset,
NewRows.datum
FROM
summarised
CROSS APPLY
(
SELECT 1 AS offset, 'NewItem1' AS datum
UNION ALL
SELECT 2 AS offset, 'NewItem2' AS datum
)
AS NewRows
WHERE
summarised.[data] = 'split'
ORDER BY
1, 2
http://sqlfiddle.com/#!18/91d7c/3
<强> 编辑: 强>
相同逻辑的稍微更短且更一致的实现:
http://sqlfiddle.com/#!18/d56f1/1
也非常快。
WITH
summarised AS
(
SELECT
*,
MAX([InternalID])
OVER (PARTITION BY [group]) AS GroupMaxID,
MAX(CASE WHEN [data] = 'split' THEN [InternalID] END)
OVER (PARTITION BY [group]) AS GroupSplitID
FROM
yourData
)
SELECT
summarised.[group] AS [group],
summarised.GroupMaxID
+ summarised.InternalID
+ NewRows.Offset AS InternalID,
NewRows.[data] AS [data]
FROM
summarised
CROSS APPLY
(
SELECT 0 AS offset, summarised.[data] WHERE summarised.InternalID <= summarised.GroupSplitID
UNION ALL
SELECT 1 AS offset, 'NewItem1' WHERE summarised.InternalID = summarised.GroupSplitID
UNION ALL
SELECT 2 AS offset, 'NewItem2' WHERE summarised.InternalID = summarised.GroupSplitID
UNION ALL
SELECT 2 AS offset, summarised.[data] WHERE summarised.InternalID > summarised.GroupSplitID
)
AS NewRows
ORDER BY
summarised.[group],
summarised.InternalID,
NewRows.Offset
答案 1 :(得分:0)
我认为这样做会
flintlabel['text'] = "Flint: " + str(flint)