计算单个 table 中其他行之后的行,这两个行都受 where 子句限制
Count rows that follows other rows in a single table both restricted with a where clause
我正在使用 SQL Server 2014。
我有一个 table,其中包含数百万个事件。主键由三列组成:
- 时间日期时间
- 用户(bigint)
- 上下文 (varchar(50))
我有另一列的值为 (nvarchar(max))
我需要计算限制在
的行数
context = 'somecontext' and value = 'value2'
及时行限制在
context = 'somecontext' and value = 'value1'
对于同一用户。
例如以下记录:
时间 用户 上下文 值
2019-02-22 14:56:57.710 359586015014836 某些上下文值 1
2019-02-22 15:13:42.887 359586015014836 somecontext value2 <------ 只需要计算这一行。
第一个后 "recorded" 15 分钟,用户和上下文相同。
我看过其他类似的问题,例如 this one or that one。
我应该在同一个 table 上进行 JOIN 吗?使用子查询?可能是 CTE?我担心性能应该是最佳的。
我们的想法是使用此版本数据库引擎中可用的查询功能。
如果我在评论中做的例子是你想要的那么你可以使用下面的代码
假设您想要 select 所有行 where context = 'c1'
,当前 value = 'v1'
,下一个值 = 'v3' if ordered by time
:
declare @t table
(
Time_ DateTime,
user_ bigint,
context varchar(50),
value_ varchar(50)
);
insert into @t values
('20000101', 1, 'c1', 'v1'),
('20000102', 1, 'c2', 'v3'),
('20000103', 1, 'c1', 'v3'),
('20000104', 2, 'c1', 'v1'),
('20000105', 2, 'c1', 'v4'),
('20000106', 2, 'c1', 'v2');
with cte as
(
select *,
lead(value_) over(partition by user_ order by time_) as next_value
from @t
where context = 'c1'
)
select *
from cte
where next_value = 'v3';
我正在使用 SQL Server 2014。
我有一个 table,其中包含数百万个事件。主键由三列组成:
- 时间日期时间
- 用户(bigint)
- 上下文 (varchar(50))
我有另一列的值为 (nvarchar(max))
我需要计算限制在
的行数context = 'somecontext' and value = 'value2'
及时行限制在
context = 'somecontext' and value = 'value1'
对于同一用户。
例如以下记录:
时间 用户 上下文 值
2019-02-22 14:56:57.710 359586015014836 某些上下文值 1
2019-02-22 15:13:42.887 359586015014836 somecontext value2 <------ 只需要计算这一行。
第一个后 "recorded" 15 分钟,用户和上下文相同。
我看过其他类似的问题,例如 this one or that one。
我应该在同一个 table 上进行 JOIN 吗?使用子查询?可能是 CTE?我担心性能应该是最佳的。
我们的想法是使用此版本数据库引擎中可用的查询功能。
如果我在评论中做的例子是你想要的那么你可以使用下面的代码
假设您想要 select 所有行 where context = 'c1'
,当前 value = 'v1'
,下一个值 = 'v3' if ordered by time
:
declare @t table
(
Time_ DateTime,
user_ bigint,
context varchar(50),
value_ varchar(50)
);
insert into @t values
('20000101', 1, 'c1', 'v1'),
('20000102', 1, 'c2', 'v3'),
('20000103', 1, 'c1', 'v3'),
('20000104', 2, 'c1', 'v1'),
('20000105', 2, 'c1', 'v4'),
('20000106', 2, 'c1', 'v2');
with cte as
(
select *,
lead(value_) over(partition by user_ order by time_) as next_value
from @t
where context = 'c1'
)
select *
from cte
where next_value = 'v3';