Sql server 当增量值重新开始时,如何排除行?

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

我是一个新手,但在这里花了很多时间研究答案。我不太清楚如何使用SQLServer2008R2创建SQL结果集,该结果集可能应该使用更现代版本的超前/滞后。我试图根据一列的顺序聚合数据,但每个序列中的实例数量可能不同。我知道序列结束的唯一方法是当下一行的序列号较低时。所以它可能会变成1-2,1-2-3-4,1-2-3,我必须弄清楚如何从中得到3个骨料

源数据是连接的表,如下所示请帮助我设置格式:

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