请问这个计算和排序该如何实现

Kingofcode 2015-02-13 09:31:51
问题是这样的:
现在有表TA

---有如下几列假定为
ID A B C D E F
1 162 2 NULL 1 2 1
1 163 60 NULL 1 60 1
1 233 60 163 61 120 2
1 234 16 163 121 136 3

原始数据只有2条 ,就是最上面A为 162 163的 为了需要我可能会将他们拆分 被拆分的具体列是B 下面两条就为第二条拆分出来的 所以原始数据第二条B的值其实为136 C为被拆分原始列A 做标记用 D和E分别B数的起始数字 F为序号

现在的问题是 我需要给他们做个总体的调整 ,未调整之前 D E F只是根据A来拆分的时候做的 所以单条看没问题 但是我现在想做总体的调整 那么需要做的效果就是F 很简单 要变成 1 2 3 4 他只是个序号
那么D 和E 就需要调整了 如果只按目前的看 那么调整后的内容为

---有如下几列假定为
ID A B C D E F
1 162 2 NULL 1 2 1
1 163 60 NULL 3 62 2
1 233 60 163 63 122 3
1 234 16 163 123 138 4


但是还有个重要问题 相同ID的A可能多条 每条可能都会拆分成多条 并且A为自增列 就是说 假设以上面两条为例 我如果只拆分A 那么拆分出来的A值是肯定大于第二条的A的
啰嗦一大堆 可能也没表述清楚 不知道大家能不能看明白 求方法。。。。多谢
...全文
339 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2015-02-13
  • 打赏
  • 举报
回复
/* 测试数据
IF OBJECT_ID('TA') IS NOT NULL
DROP TABLE TA
GO

CREATE TABLE TA(
A int,
B int,
C int,
D int,
E int,
F int
)
GO

;WITH t(A,B,C,D,E,F) AS (
SELECT 162,2,NULL,1,2,1 UNION ALL
SELECT 163,60,NULL,1,60,1 UNION ALL
SELECT 233,60,163,61,120,2 UNION ALL
SELECT 234,16,163,121,136,3
)
INSERT INTO TA
SELECT *
FROM t
*/

-- F 最简单,按 A 的次序编号
;WITH t AS (
SELECT A,
ROW_NUMBER() OVER(ORDER BY A) rn
FROM ta
)
UPDATE ta
SET F = t.rn
FROM ta, t
WHERE ta.A = t.A

-- 只要统计出之前B的合计,D、E也很好算
;WITH t AS (
SELECT ta.A,
s.PrevB
FROM ta
CROSS APPLY (SELECT ISNULL(SUM(p.B),0) PrevB
FROM ta p
WHERE p.A < ta.A
) s
)
UPDATE ta
SET ta.D = t.PrevB + 1,
ta.E = t.PrevB + ta.B
FROM ta, t
WHERE ta.A = t.A

-- 结果
SELECT *
FROM TA

          A           B           C           D           E           F
----------- ----------- ----------- ----------- ----------- -----------
162 2 NULL 1 2 1
163 60 NULL 3 62 2
233 60 163 63 122 3
234 16 163 123 138 4
Kingofcode 2015-02-13
  • 打赏
  • 举报
回复
是大家都回去了 还是没看懂我的表述 还是大家都在忙
Kingofcode 2015-02-13
  • 打赏
  • 举报
回复

这个图不知道大家看懂了没有
Tiger_Zhao 2015-02-13
  • 打赏
  • 举报
回复
/* 测试数据
DELETE FROM TA

;WITH t(A,B,C,D,E,F) AS (
SELECT 162,3,NULL,1,3,1 UNION ALL
SELECT 163,60,NULL,1,60,1 UNION ALL
SELECT 233,60,163,61,120,2 UNION ALL
SELECT 234,16,163,121,136,3 UNION ALL
SELECT 299,2,162,4,5,2
)
INSERT INTO TA
SELECT *
FROM t
*/

-- F 按 (分割前的A、当前A) 的次序编号
;WITH t AS (
SELECT A,
ROW_NUMBER() OVER(ORDER BY ISNULL(C,A), A) rn
FROM ta
)
UPDATE ta
SET F = t.rn
FROM ta, t
WHERE ta.A = t.A

-- 只要统计出之前B的合计,D、E也很好算
;WITH t AS (
SELECT ta.A,
s.PrevB
FROM ta
CROSS APPLY (SELECT ISNULL(SUM(p.B),0) PrevB
FROM ta p
WHERE p.F < ta.F -- 判断前后的改动
) s
)
UPDATE ta
SET ta.D = t.PrevB + 1,
ta.E = t.PrevB + ta.B
FROM ta, t
WHERE ta.A = t.A

-- 结果
SELECT *
FROM TA

          A           B           C           D           E           F
----------- ----------- ----------- ----------- ----------- -----------
162 3 NULL 1 3 1
163 60 NULL 6 65 3
233 60 163 66 125 4
234 16 163 126 141 5
299 2 162 4 5 2
Kingofcode 2015-02-13
  • 打赏
  • 举报
回复
只会拆一次 233不会再拆了 回楼上 意思是这样的 比如我有几条数据 有时需要将B拆分 C是我自己添加的标示 为了知道那条记录是哪条原始记录拆出来的 D和E可以理解为书的页数 对应的是本条记录的起始页 比如 B为2 那么如果它是第一行对应的就是 1 2 接下来 第二条对应的D就应该是从3开始 F最简单 就是序号 但是要注意的是 这个需要是以A为主要排序依据的,就是拆分的记录和被拆的要排在一起 例如 第一条 5 我拆成2条 那么无论拆后的那条记录A为多少 他都应该排在第一条后面 后面的依次类推
唐诗三百首 2015-02-13
  • 打赏
  • 举报
回复
不好意思木有看懂,建议提供原始数据, 处理逻辑描述, 希望结果以及对结果的必要说明.
Tiger_Zhao 2015-02-13
  • 打赏
  • 举报
回复
A=233还会拆吗?
如果不再拆,更改下排序规矩可以搞定F;否则要用递归了。

至于D、E,只要把原先按A排先后改为按F排先后也可以搞定。
Kingofcode 2015-02-13
  • 打赏
  • 举报
回复
未拆之前的记录同一个ID的也不一定就2行 也可能多行
Kingofcode 2015-02-13
  • 打赏
  • 举报
回复
楼上可能没注意我说的红色部分,这次的情况是第一条没有被拆分所以,我只需要按A来获取row_number()就可以直接复制给F了 但是实际上我可能第一行也给拆分 而且可能在拆分第二条之后拆分 那么这时候可能直接以A来获取row_number复制给F就不行了 整体的也就不行了 因为我的拆分的记录是要和未拆之前的记录排在一起的 以上面这个为例 如果我也拆了第一条 那么可能就多了一行,而且我拆第一行如果在第二行之后那么记录可能就是这样的:

---有如下几列假定为 
ID         A                  B            C            D          E              F
1          162               3            NULL       1             3           1
1           163              60            NULL      1           60            1
1            233             60            163      61          120            2
1            234             16            163     121          136            3
1            299             2             162       4            5            2
那么结果应该变成这样的:

---有如下几列假定为 
ID         A                  B            C            D          E              F
1          162               3            NULL       1             3           1
1          163              60            NULL       6            65            3
1          233             60            163        66           125            4
1          234             16            163        126          141            5
1          299             2             162        4             5            2
就是说被拆开的记录 整体排序也是要按照未拆之前来排的

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧