Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将表拆分为具有重复属性的窗口_Sql_Sql Server_Tsql_Window Functions - Fatal编程技术网

Sql 将表拆分为具有重复属性的窗口

Sql 将表拆分为具有重复属性的窗口,sql,sql-server,tsql,window-functions,Sql,Sql Server,Tsql,Window Functions,我的标题很糟糕,因为我不知道如何描述这个挑战。如果有人能想出一个更具描述性的标题,我会喜欢编辑。希望我的输入/期望的输出将有助于解释。以下是一些示例输入数据: create table #input ( num varchar(10), code varchar(10), event_date date ) insert into #input (num, code, event_date) values('123456', 'Active', '2007-09-10'

我的标题很糟糕,因为我不知道如何描述这个挑战。如果有人能想出一个更具描述性的标题,我会喜欢编辑。希望我的输入/期望的输出将有助于解释。以下是一些示例输入数据:

create table #input (
    num varchar(10),
    code varchar(10),
    event_date date
)

insert into #input (num, code, event_date)
values('123456', 'Active', '2007-09-10'),
      ('123456', 'Active', '2010-09-15'),
      ('123456', 'Active', '2010-09-24'),
      ('123456', 'Inactive', '2018-09-17'),
      ('123456', 'Inactive', '2019-01-01'),
      ('123456', 'Active', '2019-02-08')

select *
from #input
order by event_date
我想用相同的数字标记每组num+代码的每条记录。但是,我希望时间段保持分开。以下是期望的结果:

create table #result (
    num varchar(10),
    code varchar(10),
    event_date date,
    tag int
)

insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
      ('123456', 'Active', '2010-09-15', 1),
      ('123456', 'Active', '2010-09-24', 1),
      ('123456', 'Inactive', '2018-09-17', 2),
      ('123456', 'Inactive', '2019-01-01', 2),
      ('123456', 'Active', '2019-02-08', 3)

select *
from #result
order by event_date
很明显,像这样的普通窗口分区

select *, row_number() over(partition by num, code order by event_date) rn
from #input
order by event_date
…不起作用,因为没有要划分的字段会分割两个“活动”组(两个组,因为它们发生在两个时间范围内)。我怎样才能达到我想要的结果?我有一种预感,一系列的
lag()
lead()
函数可能会起作用,但我无法得到任何有意义的结果

或者,我如何实现结果,使类别重叠一个

create table #result_new (
    num varchar(10),
    code varchar(10),
    event_date date,
    tag int
)

insert into #result (num, code, event_date, tag)
values('123456', 'Active', '2007-09-10', 1),
      ('123456', 'Active', '2010-09-15', 1),
      ('123456', 'Active', '2010-09-24', 1),
      ('123456', 'Inactive', '2018-09-17', 1),
      ('123456', 'Inactive', '2019-01-01', 2),
      ('123456', 'Active', '2019-02-08', 2)

select *
from #result_new
order by event_date

LAG
让你走到了一半,但不是全程。您可以使用
LAG
检查最后一行的值,并创建(我称之为)一个开关。然后,您可以使用
SUM
窗口函数和
ROWs-BETWEEN
子句来获取
标记的值:

WITH CTE AS(
      SELECT num,
             code,
             event_date,
             CASE WHEN code = LAG(code) OVER (PARTITION BY num ORDER BY event_date) THEN 0 ELSE 1 END AS Switch
      FROM #input)
SELECT num,
       code,
       event_date,
       SUM(Switch) OVER (PARTITION BY num ORDER BY event_date
                         ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS tag
FROM CTE;

明亮的您能解释一下无界前一行和当前行之间的
行添加了什么吗?删除它似乎会得到相同的结果。在
OVER
子句中使用
orderby
时,这实际上是默认的作用域@OverflowingTheGlass。我宁愿给它下定义,以防万一有一天它没有意义——谢谢。知道如何让分组包含下一条记录吗?例如,在这种情况下,只有两组:
1
将覆盖前四行,
2
将覆盖最后两行。因此,当
code
切换时,该记录切换的位置应包含在上一个分组中。我不确定是否理解@OverflowingTheGlass。上面的查询返回问题中表
#result
中的结果集;这不对吗?如果不是,那么你需要修改你的问题,以反映你所追求的结果。不,你是正确的。我移动了一下球门柱——如果与原来的问题有太多的出入,我很乐意发布一个新的问题。为了以防万一,我用其他结果编辑了我的问题