Sql server 当增量值重新开始时,如何排除行?
我是一个新手,但在这里花了很多时间研究答案。我不太清楚如何使用SQLServer2008R2创建SQL结果集,该结果集可能应该使用更现代版本的超前/滞后。我试图根据一列的顺序聚合数据,但每个序列中的实例数量可能不同。我知道序列结束的唯一方法是当下一行的序列号较低时。所以它可能会变成1-2,1-2-3-4,1-2-3,我必须弄清楚如何从中得到3个骨料 源数据是连接的表,如下所示请帮助我设置格式:Sql server 当增量值重新开始时,如何排除行?,sql-server,tsql,sql-server-2008-r2,Sql Server,Tsql,Sql Server 2008 R2,我是一个新手,但在这里花了很多时间研究答案。我不太清楚如何使用SQLServer2008R2创建SQL结果集,该结果集可能应该使用更现代版本的超前/滞后。我试图根据一列的顺序聚合数据,但每个序列中的实例数量可能不同。我知道序列结束的唯一方法是当下一行的序列号较低时。所以它可能会变成1-2,1-2-3-4,1-2-3,我必须弄清楚如何从中得到3个骨料 源数据是连接的表,如下所示请帮助我设置格式: recordID instanceDate moduleID iResult interactionN
recordID instanceDate moduleID iResult interactionNum
1356 10/6/15 16:14 1 68 1
1357 10/7/15 16:22 1 100 2
1434 10/9/15 16:58 1 52 1
1435 10/11/15 17:00 1 60 2
1436 10/15/15 16:57 1 100 3
1437 10/15/15 16:59 1 100 4
在本例中,我需要找到一种方法,根据最后一列中的值,将前2行与后4行分开
我希望最终得到的结果集如下所示,它根据分组对iResult列进行平均,并从分组中获取第一个instanceDate:
instanceDate moduleID iResult
10/6/15 1 84
10/9/15 1 78
如果我能找到一种方法来分离这些组,我可以使用MIN和AVG来聚合得到这个结果。数据是按instanceDate排序的。请忽略此处的日期格式,然后当查询找到interactionNum为的行时,interactionNum和组分离应该发生,因为interactionNum不确定应该使用什么ModuleID,但我猜您正在寻找类似的内容:
instanceDate ModuleID iResult interactionNum
10/6/15 16:10 1 68 1
10/6/15 16:14 1 100 2
10/15/15 16:57 1 100 3
10/15/15 16:59 1 100 4
select min (instanceDate), [moduleID], avg([iResult])
from (
select *,row_number() over (partition by [moduleID] order by instanceDate) as RN
from Table1
) X
group by [moduleID], RN - [interactionNum]
这里的想法是为每个moduleid创建一个带有行号的运行编号,然后使用该编号和InteractionNum之间的差异作为分组标准
这里的例子是我的解决方案,虽然应该说,@JamesZ的答案更简洁 我创建了一个名为newinstance的新字段,无论instanceNumber是1,它都是1。然后,我创建了一个名为rollinginstance to group on的滚动sumnewinstance 将上次选择更改为从cte2中选择*以显示我添加的所有字段
IF OBJECT_ID('tempdb..#tmpData') IS NOT NULL
DROP TABLE #tmpData
CREATE TABLE #tmpData (recordID INT, instanceDate DATETIME, moduleID INT, iResult INT, interactionNum INT)
INSERT INTO #tmpData
SELECT 1356,'10/6/15 16:14',1,68,1 UNION
SELECT 1357,'10/7/15 16:22',1,100,2 UNION
SELECT 1434,'10/9/15 16:58',1,52,1 UNION
SELECT 1435,'10/11/15 17:00',1,60,2 UNION
SELECT 1436,'10/15/15 16:57',1,100,3 UNION
SELECT 1437,'10/15/15 16:59',1,100,4
;WITH cte1 AS
(
SELECT *,
CASE WHEN interactionNum=1 THEN 1 ELSE 0 END AS newinstance,
ROW_NUMBER() OVER(ORDER BY recordID) as rowid
FROM #tmpData
), cte2 AS
(
SELECT *,
(select SUM(newinstance) from cte1 b where b.rowid<=a.rowid) as rollinginstance
FROM cte1 a
)
SELECT MIN(instanceDate) AS instanceDate, moduleID, AVG(iResult) AS iResult
FROM cte2
GROUP BY moduleID, rollinginstance
当我觉得这很难的时候,你让它看起来很容易。谢谢你,谢谢你。唯一的问题是,如果有人从interactionNum=1开始跳过,例如,序列变为1-2、2-3-4,那么结果集将错过第二组,这很少见,但可能会发生
IF OBJECT_ID('tempdb..#tmpData') IS NOT NULL
DROP TABLE #tmpData
CREATE TABLE #tmpData (recordID INT, instanceDate DATETIME, moduleID INT, iResult INT, interactionNum INT)
INSERT INTO #tmpData
SELECT 1356,'10/6/15 16:14',1,68,1 UNION
SELECT 1357,'10/7/15 16:22',1,100,2 UNION
SELECT 1434,'10/9/15 16:58',1,52,1 UNION
SELECT 1435,'10/11/15 17:00',1,60,2 UNION
SELECT 1436,'10/15/15 16:57',1,100,3 UNION
SELECT 1437,'10/15/15 16:59',1,100,4
;WITH cte1 AS
(
SELECT *,
CASE WHEN interactionNum=1 THEN 1 ELSE 0 END AS newinstance,
ROW_NUMBER() OVER(ORDER BY recordID) as rowid
FROM #tmpData
), cte2 AS
(
SELECT *,
(select SUM(newinstance) from cte1 b where b.rowid<=a.rowid) as rollinginstance
FROM cte1 a
)
SELECT MIN(instanceDate) AS instanceDate, moduleID, AVG(iResult) AS iResult
FROM cte2
GROUP BY moduleID, rollinginstance