按一组数据分组,并将每个部分中的项目与 T SQL 中的其他部分分开

Group by a set of data and order items in each part separately from other parts in T SQL

我有一组数据,其中包含 2 个字段 "ActivationTime",类型为 DATETIME 和 "Score",类型为 INT。

我想根据以下规则对所有数据进行分组:

(1) 每组数据之间最多相差5天(对应"ActivationTime"值。注意第一个"ActivationTime"是最新的"ActivationTime"一组数据。例如,在下面的示例中,第一个 "ActivationTime" 将是 '2017-11-24 09:45:00.000',其分数 = 1)

(2) 分组数据每个部分中的项目必须按 "Score" 值 "SEPARATELY" 来自其他分组数据部分

的顺序

有人可以帮助我吗?

编辑:例如想象@ExampleTabel 如下:

Score                  ActivationTime
-------------------------------------------
  9               '2017-11-20 09:37:00.000'
  5               '2017-11-21 09:39:00.000'
  4               '2017-11-22 09:40:00.000'
  3               '2017-11-23 09:43:00.000'
  1               '2017-11-24 09:45:00.000'
  12              '2017-11-22 09:49:00.000'
  7               '2017-11-17 09:38:00.000'
  2               '2017-11-15 09:41:00.000'
  0               '2017-11-14 09:44:00.000'
  15              '2017-11-13 09:47:00.000'
  7               '2017-11-12 09:46:00.000'
  20              '2017-11-11 09:42:00.000'
  4               '2017-11-10 09:78:00.000'

我除了生成的结果:

Score                 ActivationTime             Category
---------------------------------------------------------------
  12             '2017-11-20 09:49:00.000'          1
  9              '2017-11-20 09:37:00.000'          1
  5              '2017-11-21 09:39:00.000'          1
  4              '2017-11-22 09:40:00.000'          1
  3              '2017-11-23 09:43:00.000'          1
  1              '2017-11-24 09:45:00.000'          1

  15             '2017-11-13 09:47:00.000'          2
  7              '2017-11-17 09:38:00.000'          2
  2              '2017-11-15 09:41:00.000'          2
  0              '2017-11-14 09:44:00.000'          2

  20             '2017-11-11 09:42:00.000'          3
  7              '2017-11-12 09:46:00.000'          3
  3              '2017-11-20 09:37:57.570'          3
  4              '2017-11-10 09:78:00.000'          3

根据您的意见,这就是您在 N 天前的做法。

首先,我创建了一个虚拟 table,其中包含我想返回多少天的数字。这个 table 然后我在我的光标中循环以创建我的 CTE 语句。最后我合并了我所有的 CTE,然后按激活时间和分数对它们进行排序

/*SCRIPT */

DECLARE @NDaysAgo nvarchar(2) = 20 --Change this based on how many days you want to go back
DECLARE @Number nvarchar(2)
DECLARE @sqlCreateNumbers nvarchar(max)
DECLARE @AliasName nvarchar(50)
DECLARE @SQL nvarchar(max)
DECLARE @SQLUnion nvarchar(max)
 DECLARE @crlf nvarchar(max)
 SET @crlf = CHAR(13)
DECLARE @SQLTotal nvarchar(MAX)

Set @sqlCreateNumbers = '

IF EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N''[dbo].[numbers]'') AND type in (N''U''))
DROP TABLE [dbo].[numbers];

SELECT TOP '+@NDaysAgo+' IDENTITY(int,0,1) AS n 
into dbo.numbers
FROM MASTER..spt_values a, MASTER..spt_values b;

CREATE UNIQUE CLUSTERED INDEX idx_1 ON numbers(n);


'
PRINT @sqlCreateNumbers

EXEC (@sqlCreateNumbers)


DECLARE SqlCur CURSOR FOR
Select DaysAgo = N,Alias = 'Today'+cast(N as nvarchar(50))
from dbo.Numbers
OPEN SqlCur
FETCH NEXT FROM SqlCur
INTO @Number,@AliasName
IF (@@FETCH_STATUS>=0)
BEGIN
SET @SQL = 'with '+@AliasName+' as (
Select '''+@AliasName+''' as SourceName,Score,ActivationTime
from dbo.testactivation
Where cast(ActivationTime as date) = cast(dateadd(dd,'+@Number+',GETDATE()) as date)

)'

SET @SQLUnion = 'Select * from '+@AliasName+''

--PRINT @SQL
FETCH NEXT FROM SqlCur INTO @Number,@AliasName
 END
 WHILE (@@FETCH_STATUS<>-1)

 BEGIN
 IF (@@FETCH_STATUS<>-2)

 SET @SQL = @SQL + ','+@AliasName+' as (
Select '''+@AliasName+''' as SourceName,Score,ActivationTime
from dbo.testactivation
Where cast(ActivationTime as date) = cast(dateadd(dd,-'+@Number+',GETDATE()) as date)

)'
SET @SQLUnion =  @SQLUnion + @crlf+ ' union all Select * from '+@AliasName+''
--PRINT @SQL

FETCH NEXT FROM SqlCur INTO @Number,@AliasName
END

 CLOSE SqlCur
 DEALLOCATE SqlCur


SET @SQLTotal = @SQL + 'Select * from ( '+@SQLUnion+ ' ) x ORDER BY ACTIVATIONTIME DESC, SCORE DESC'

PRINT @SQLTotal --This will not show you all records since there is a limit to how much text it can show
Select @SQLTotal -- If you select it you can see the query

EXEC(@SQLTotal) --This will execute your statement, so you can see your descired result

编辑 如果你不能使用你无法获得 NDays 的变量,那么你必须对其进行硬编码。

一次查询

Select 'Data' as SourceName,Score,ActivationTime
from dbo.testactivation
Where cast(ActivationTime as date) between cast(dateadd(dd,0,GETDATE()) as date)
and cast(dateadd(dd,-20,GETDATE()) as date)
order by ActivationTime desc,score desc

结果

从你所说的来看,你似乎想要这样的东西。

select
Score, ActivationTime, (rnk - 1) / 5 grp
from (
    select
        Score, ActivationTime, dense_rank()over(order by cast(ActivationTime as date) desc) rnk
from
    mytable
) t
order by grp, Score desc

你应该给出一些样本数据和你希望得到更好帮助的结果