需要一个简单的查询来计算SQL Server中的序列长度
我有一个视图,表示每个用户到表内系统的连接状态,如下所示:需要一个简单的查询来计算SQL Server中的序列长度,sql,sql-server,Sql,Sql Server,我有一个视图,表示每个用户到表内系统的连接状态,如下所示: --------------------------------------- |id | date | User | Connexion | |1 | 01/01/2018 | A | 1 | |2 | 02/01/2018 | A | 0 | |3 | 03/01/2018 | A | 1 | |4 | 04/01/2018 |
---------------------------------------
|id | date | User | Connexion |
|1 | 01/01/2018 | A | 1 |
|2 | 02/01/2018 | A | 0 |
|3 | 03/01/2018 | A | 1 |
|4 | 04/01/2018 | A | 1 |
|5 | 05/01/2018 | A | 0 |
|6 | 06/01/2018 | A | 0 |
|7 | 07/01/2018 | A | 0 |
|8 | 08/01/2018 | A | 1 |
|9 | 09/01/2018 | A | 1 |
|10 | 10/01/2018 | A | 1 |
|11 | 11/01/2018 | A | 1 |
---------------------------------------
目标输出是按日期获取成功和失败连接顺序的计数,因此输出如下
---------------------------------------------------------------
|StartDate EndDate User Connexion Length|
|01/01/2018 | 01/01/2018 | A | 1 | 1 |
|02/01/2018 | 02/01/2018 | A | 0 | 1 |
|03/01/2018 | 04/01/2018 | A | 1 | 2 |
|05/01/2018 | 07/01/2018 | A | 0 | 3 |
|08/01/2018 | 11/01/2018 | A | 1 | 4 |
---------------------------------------------------------------
这就是所谓的缺口和岛屿问题。您的版本的最佳解决方案是行号不同:
select user, min(date), max(date), connexion, count(*) as length
from (select t.*,
row_number() over (partition by user order by date) as seqnum,
row_number() over (partition by user, connexion order by date) as seqnum_uc
from t
) t
group by user, connexion, (seqnum - seqnum_uc);
为什么这样做有点难解释。一般来说,我发现如果你盯着子查询的结果看,你会发现你所关心的组之间的差异是恒定的
注意:列的名称不应使用
user
或date
。这些是SQL中的关键字(一种或另一种类型)。如果您确实使用了转义符,那么您必须用转义符将SQL弄得乱七八糟,这只会使代码更难编写、读取和调试。到目前为止,您做了哪些尝试?请发布您尝试过的SQL并告诉我们为什么它不起作用,好吗?[User]
和[Date]
请有限地[User]
,因为User
是一个保留字date
只是一个关键字,所以它可以用于未加引号的对象名称,但是,我同意它应该是[加引号]。