我有一组数据有2个字段“ActivationTime”,它是DATETIME&的类型。 “得分”是INT的类型。
我想根据这条规则对所有数据进行分组:
(1)每组中的数据必须相互间隔最多5天(对应于“ActivationTime”值。请注意,第一个“ActivationTime”是数据集中的最新“ActivationTime”。例如,在下面样品首先“ActivationTime”将是'2017-11-24 09:45:00.000',其得分= 1)
(2)分组数据的每个部分中的项目必须按“分数”值从“数据的其他分组部分”“单独”排序
如果有可能,有人可以帮助我吗?
编辑:例如想象@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
答案 0 :(得分:1)
从你所说的话来看,你似乎想要这样的东西。
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
您应该提供一些示例数据以及您希望获得更好帮助的结果
答案 1 :(得分:0)
根据您的评论,这是您在N Days返回时的方式。
首先,我创建一个虚拟表,其中包含我想要返回多少天的数字。这个表然后在我的光标中循环以创建我的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