Sql 顺序链接数据的滚动求和
我正在处理一个大型的遗留数据集,其中包含顺序相关的数据,我没有文字来解释这些数据,因此我制作了一幅漂亮的绘画图像。这当然不是真正的数据集,但很接近。本例中有三个序列 每个记录都有一个ID和一个值。它还有一个指向下一个相关ID的指针。序列长度是随机的,当下一个相关ID达到0值时停止。所有记录在一个序列中只使用一次,这意味着它们不能合并或拆分。一个序列只能由一条记录组成 我需要完成的是使用SQL查询(SQL server 2014)获取序列中每个记录的滚动和。如果序列中有公共标识符,我知道如何执行此操作,但在本例中没有 我已经能够在Excel中通过查找上一个总和(如果存在)并添加当前值来完成它(不管它值多少)。但我无法将其转换为SQL。有人知道从哪里开始实现SQL中“滚动求和结果”列的最终目标吗Sql 顺序链接数据的滚动求和,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在处理一个大型的遗留数据集,其中包含顺序相关的数据,我没有文字来解释这些数据,因此我制作了一幅漂亮的绘画图像。这当然不是真正的数据集,但很接近。本例中有三个序列 每个记录都有一个ID和一个值。它还有一个指向下一个相关ID的指针。序列长度是随机的,当下一个相关ID达到0值时停止。所有记录在一个序列中只使用一次,这意味着它们不能合并或拆分。一个序列只能由一条记录组成 我需要完成的是使用SQL查询(SQL server 2014)获取序列中每个记录的滚动和。如果序列中有公共标识符,我知道如何执行
您需要类似于递归查询的东西 你可以用CTE做这个。这是对您的数据的测试(您寻找的列是“cumul”,其他列用于帮助了解发生了什么): 要按相反的顺序执行此操作。。。可能不止一种方法。从我的头顶上,我会得到每个链(由其lastid标识)的最小和最大累积值,然后我会应用阶梯算法——在这种情况下,递减滚动和是VALMIN+VALMAX-rolling 比如
WITH sequenza AS (
SELECT
id,
value,
nextid,
id AS lastid,
value as cumul
FROM
items
WHERE nextid = 0
UNION ALL
SELECT
curr.id,
curr.value,
curr.nextid,
prev.lastid,
prev.cumul + curr.value AS cumul
FROM
items AS curr
INNER JOIN sequenza AS prev
ON prev.id = curr.nextid
),
sequenza2 AS (
SELECT
id,
value,
nextid,
id AS lastid,
value as cumul
FROM
items
WHERE nextid = 0
UNION ALL
SELECT
curr.id,
curr.value,
curr.nextid,
prev.lastid,
prev.cumul + curr.value AS cumul
FROM
items AS curr
INNER JOIN sequenza2 AS prev
ON prev.id = curr.nextid
)
SELECT sequenza.*, m1+m2-cumul AS cumulasc FROM sequenza
JOIN (
SELECT lastid, MIN(cumul) AS m1, MAX(cumul) AS m2
FROM sequenza2
GROUP BY lastid
) AS cirpo ON (sequenza.lastid = cirpo.lastid)
ORDER BY sequenza.lastid, cumul DESC
是否有序列的合并,换句话说,两行可以使用同一个指针?@Charlieface这是一个重要的细节。它们不能合并。我已经把这篇文章放在了主要的帖子里。这看起来很有希望!但当我执行查询时,序列似乎发生了翻转(从序列中的最后一个计数到第一个计数),有没有办法扭转这种局面?@Monthy编辑的答案…谢谢!你的回答几乎就是我需要的。我注意到它将序列中的最后一项作为第一个和(例如:在id 31处,累积结果是82,这是序列中的最后一个值,下一个id将正确地添加29,这是id 31中的值)。为了使其与Excel示例完全相同,我从联接和公式中删除了m1,并添加了如下当前值:“选择sequenza.*,m2 cumul+值作为sequenza中的cumulasc”。这个现在很好用。再次感谢!
WITH sequenza AS (
SELECT
id,
value,
nextid,
id AS lastid,
value as cumul
FROM
items
WHERE nextid = 0
UNION ALL
SELECT
curr.id,
curr.value,
curr.nextid,
prev.lastid,
prev.cumul + curr.value AS cumul
FROM
items AS curr
INNER JOIN sequenza AS prev
ON prev.id = curr.nextid
)
SELECT * FROM sequenza
WHERE id = 31;
WITH sequenza AS (
SELECT
id,
value,
nextid,
id AS lastid,
value as cumul
FROM
items
WHERE nextid = 0
UNION ALL
SELECT
curr.id,
curr.value,
curr.nextid,
prev.lastid,
prev.cumul + curr.value AS cumul
FROM
items AS curr
INNER JOIN sequenza AS prev
ON prev.id = curr.nextid
),
sequenza2 AS (
SELECT
id,
value,
nextid,
id AS lastid,
value as cumul
FROM
items
WHERE nextid = 0
UNION ALL
SELECT
curr.id,
curr.value,
curr.nextid,
prev.lastid,
prev.cumul + curr.value AS cumul
FROM
items AS curr
INNER JOIN sequenza2 AS prev
ON prev.id = curr.nextid
)
SELECT sequenza.*, m1+m2-cumul AS cumulasc FROM sequenza
JOIN (
SELECT lastid, MIN(cumul) AS m1, MAX(cumul) AS m2
FROM sequenza2
GROUP BY lastid
) AS cirpo ON (sequenza.lastid = cirpo.lastid)
ORDER BY sequenza.lastid, cumul DESC