- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
表中的给定数据具有任意间隔(不是日期/时间!!),定义如下:
START float
END float
VALUE varchar(40)
例如
START END VALUE
----- --- ------
0 1 Banana
1 3 Banana
3 4 Orange
4 7 Orange
7 8 Apple
8 9 Apple
9 10 Apple
10 15 Apple
20 22 Apple
22 23 Apple
23 28 Banana
28 30 Banana
etc..
如何汇总数据,以便对于连续的时间间隔,仅列出一个值。 IE。查询结果应如下所示:
START END VALUE
----- --- ------
0 3 Banana
3 7 Orange
7 15 Apple
20 23 Apple
23 30 Banana
请注意上面 15 和 20 之间的差距。我正在处理相当多的数据(~500k 行),但不经常运行查询。所以效率是最好的。可以在不使用光标的情况下完成此操作吗?
(注意:使用 SQL2008R2,因此无法利用较新的功能(如果存在)
谢谢!
最佳答案
这应该适合你:
DECLARE @T TABLE (Start INT, [End] INT, Value VARCHAR(100));
INSERT @T (Start, [End], Value)
VALUES
(0, 1, 'Banana'), (1, 3, 'Banana'), (3, 4, 'Orange'), (4, 7, 'Orange'),
(7, 8, 'Apple'), (8, 9, 'Apple'), (9, 10, 'Apple'), (10, 15, 'Apple'),
(20, 22, 'Apple'), (22, 23, 'Apple'), (23, 28, 'Banana'), (28, 30, 'Banana');
WITH CTE AS
( SELECT t.[Start],
t.[End],
t.[value],
IsStart = ISNULL(c.IsStart, 1)
FROM @T AS T
OUTER APPLY
( SELECT TOP 1 IsStart = 0
FROM @T AS T2
WHERE T2.Value = T.Value
AND T2.[End] = T.Start
) AS c
)
SELECT Value, Start = MIN(Start), [End] = MAX([End])
FROM CTE AS T
OUTER APPLY
( SELECT SUM(IsStart)
FROM CTE AS T2
WHERE T2.Value = T.Value
AND T2.Start <= T.Start
) g (GroupingSet)
GROUP BY Value, GroupingSet
ORDER BY Start;
第一步是识别作为新范围开始的每条记录。这部分:
SELECT t.[Start],
t.[End],
t.[value],
IsStart = ISNULL(c.IsStart, 1)
FROM @T AS T
OUTER APPLY
( SELECT TOP 1 IsStart = 0
FROM @T AS T2
WHERE T2.Value = T.Value
AND T2.[End] = T.Start
) AS c
将给出:
Start End value IsStart
0 1 Banana 1
1 3 Banana 0
3 4 Orange 1
4 7 Orange 0
7 8 Apple 1
8 9 Apple 0
9 10 Apple 0
10 15 Apple 0
20 22 Apple 1
然后,您可以通过识别在当前记录之前开始的范围数来创建唯一组,本质上是添加按值分区的 IsStart
列的运行总计。这就是这里正在做的事情:
SELECT *
FROM CTE AS T
OUTER APPLY
( SELECT SUM(IsStart)
FROM CTE AS T2
WHERE T2.Value = T.Value
AND T2.Start <= T.Start
) g (GroupingSet);
给予:
Start End value IsStart GroupingSet
0 1 Banana 1 1
1 3 Banana 0 1
3 4 Orange 1 1
4 7 Orange 0 1
7 8 Apple 1 1
8 9 Apple 0 1
9 10 Apple 0 1
10 15 Apple 0 1
20 22 Apple 1 2 -- SECOND NON CONTINUOUS RANGE FOR APPLES
22 23 Apple 0 2
23 28 Banana 1 2 -- SECOND NON CONTINUOUS RANGE FOR BANANAS
28 30 Banana 0 2
最后,您可以按值聚合分组,并使用此标识符列来标识唯一组。
您还可以通过交叉连接到数字表将每个范围扩展为行来实现此目的(为简洁起见,我使用了 master..spt_values
):
WITH CTE AS
( SELECT t.[value],
Number = t.Start + v.Number,
GroupingSet = t.Start + v.Number - ROW_NUMBER() OVER(PARTITION BY t.[value] ORDER BY t.Start + v.Number)
FROM @T AS T
INNER JOIN Master..spt_values v
ON v.[Type] = 'P'
AND v.Number < (t.[End] - t.[Start])
)
SELECT Value, [Start] = MIN(Number), [End] = MAX(Number)
FROM CTE
GROUP BY GroupingSet, Value;
这样做的缺点是,如果您有很多行/大范围,它可能会占用大量内存。扩展范围后,这仅使用 Itzik Ben-Gan's Gaps and Islands Solutions 中描述的使用排名函数的方法。
关于sql-server - 总结区间数据的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24368712/
我在 Python 中使用 matplotlib,并制作了一个带条形的直方图。现在,当直方图出现时,仅 5 的倍数出现在 x 轴上,1000 的倍数出现在 y 轴上。对于 y 轴,这完全没有问题,但对
我正在使用 JavaScript 和 jQuery。我有以下脚本每 30 秒提醒一次 hi。 $(document).ready( function() { alert("hi"); setI
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
在 Numpy(python 包)中,可以使用语法 numpy.linspace(minValue, MaxValue, numberOfSamples) 构造 float 的离散区间。 . 我看到
所以我想在 -3 到 3 的区间内制作一些数字,以便在下面绘制这些函数,所以我想要尽可能多的数字。 我这样做: double k[601]; double y[601]; for (int i = 0
我有一个 Postgresql 表,用于存储有关计划进程的信息,包括上次执行进程的时间。不同的进程对其运行频率有不同的要求。 我列出了需要重新运行的进程列表: SELECT * FROM proces
如何正确使用此类带日期间隔的查询 @SqlUpdate("delete fromlogin where created < now() - ':days days' :: interval") v
我正在尝试计算图中的间隔,我在维基百科上找到了算法的数学描述: http://en.wikipedia.org/wiki/Interval_(graph_theory) H = { n0 }
我有一个基于 Informix-SQL 的 Pawnshop 应用程序,该应用程序根据黄金的重量和纯度计算应向客户贷出多少钱。当铺的最低贷款额为 5.00 美元。当铺员工通常会借出以 5 或 0 结尾
我将 NHibernate 与代码映射一起使用,并且我有一个由此公式创建的属性。 Property(x => x.IsInOverdue, mapper => mapper .Fo
我正在尝试从头开始为 Beta 分布编写卡方拟合优度检验,而不使用任何外部函数。下面的代码报告“1”适合,即使来自 scipy.stats 的 kstest 返回零。数据是正常分布的,所以我的函数也应
如何在 C# 中将任何值四舍五入到 10 区间?例如,如果我有 11,我希望它返回 10,如果我有 136,那么我希望它返回 140。 我可以很容易地用手做 return ((int)(number
如何在 Go 中表示 PostgreSQL 区间? 我的结构看起来像这样: type Product struct { Id int Name
我想编写一个函数,将数值限制在封闭的 0,1 区间内: func clamp01(_ value:T) -> T { return value 1 ? 1 : value } 在 Swift 3
我有一个简单的表格,用于存储来自在线仪表的降水读数。这是表定义: CREATE TABLE public.precip ( gauge_id smallint,
a = y def __gt__(self, y): return not self.x > y def __eq__(self, y): return
我正在处理 pandas 数据框 D=pd.DataFrame(data=[1.0,2.0,2.0,2.0,5.0,3.0,2.0,2.0,5.0,5.0,8.0,1.0]) 我识别低于特定阈值的值
我编写了一些C++代码来解决此问题: #include #include using namespace std; unsigned int countSetBits(unsigned int n
好的,我知道之前有人用一个有限的缩放示例问过这个问题 [-1, 1]间隔 [a, b] Different intervals for Gauss-Legendre quadrature in num
我是一名优秀的程序员,十分优秀!