T-SQL从组中删除重复项,但不从每个组中获取前1名

T-SQL从组中删除重复项,但不从每个组中获取前1名,sql,sql-server,tsql,window-functions,gaps-and-islands,Sql,Sql Server,Tsql,Window Functions,Gaps And Islands,我不想从每个小组中获得前1名!请注意我在问题的最后部分所作的解释 我有以下几行: | Code | Type | SubType | Date | |:----:|:----:|:-------:|:----------:| | 100 | 10 | 1 | 17.12.2019 | | 100 | 10 | 2 | 18.12.2019 | | 100 | 10 | 2 | 19.12.2019 | | 100 | 10

我不想从每个小组中获得前1名!请注意我在问题的最后部分所作的解释

我有以下几行:

| Code | Type | SubType |    Date    |
|:----:|:----:|:-------:|:----------:|
|  100 |  10  |    1    | 17.12.2019 |
|  100 |  10  |    2    | 18.12.2019 |
|  100 |  10  |    2    | 19.12.2019 |
|  100 |  10  |    1    | 20.12.2019 |
我需要的是根据代码、类型和子类型列来创建行组。但我不仅要保留Dead列,而且必须从代码中删除重复行,从中间的那些组的类型和子类型列如下:

| Code | Type | SubType |    Date    |
|:----:|:----:|:-------:|:----------:|
|  100 |  10  |    1    | 17.12.2019 |
|  100 |  10  |    2    | 18.12.2019 |
|  100 |  10  |    1    | 20.12.2019 |
让我进一步解释导致这种情况的场景,因此我需要在向最终用户显示之前清理数据。我有一个历史表,它有4列代码、类型、子类型和日期。此表的每一行显示在特定日期该行字段值发生的更改。例如,在上面的示例中,行在4个不同的日期发生了4次更改。首先,在2019年12月17日生成了代码为100、类型为10、子类型为1的行。2019年12月18日,子类型已更改为2。第二天,2019年12月19日,子类型再次更改为2,这在我的案例中是重复的。最后,子类型在2019年12月20日再次更改为1。事实上,我不需要显示第三个更改,因为它在我的案例中是重复的


我尝试使用按代码、按日期的类型和子类型顺序的行数分割,但没有成功。

您希望保留发生更改的日期。我的建议滞后于日期:

另一种方法是对每列进行延迟,然后检查每个值是否有变化。这不仅麻烦,而且如果涉及空值,逻辑会变得更糟


这里的逻辑是:CTS组合的前一个日期是否与前一个日期相同?如果是这样,请丢弃该记录。

在我看来,这似乎是一个缺口和孤岛问题。以下是一种使用行号的方法:

这通过将代码、类型分区上的行号与代码、类型、子类型分区上的行号之差来定义组。然后,我们选择每组的第一条记录,再次使用行号

:


发布完全相同的问题不会产生新的问题。。。如果你觉得我标记为重复的问题无助于解释原因,你不能这样做。预期结果中的内容肯定是数据中的第一行。如果不是这样,请在原始问题中提供更多的示例数据,解释链接的副本为什么不是副本,并显示您的尝试。@Larnu:重复发布同一问题的想法是正确的。然而,我不确定作为重复链接的解决方案对这个问题的适用性有多好。这个问题似乎是一个缺口和孤岛问题。嗯,你可能是对的,@GMB。这些微小的样本数据和预期的结果并不能真正帮助我们判断是哪一个。然而,仍然有很多类似的例子。我将在OP的原始问题中添加一个。然而,这是stuill与旧版本的完全相同的版本,因此应该关闭。
select t.*
from (select t.*,
             lag(date) over (partition by code, type, subtype order by date) as prev_cts_date,
             lag(date) over (order by date) as prev_date
      from t
     ) t
where prev_cts_date is null or prev_cts_date <> prev_date;
select code, type, SubType, Date
from (
    select
        t.*,
        row_number() over(partition by code, type, rn1 - rn2 order by date) rn
    from (
        select 
            t.*,
            row_number() over(partition by code, type order by date) rn1,
            row_number() over(partition by code, type, SubType order by date) rn2
        from mytable t
    ) t
) t
where rn = 1
code | type | SubType | Date ---: | ---: | ------: | :--------- 100 | 10 | 1 | 17.12.2019 100 | 10 | 2 | 18.12.2019 100 | 10 | 1 | 20.12.2019