Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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 server T-SQL删除“重复/不感兴趣”的数据行_Sql Server_Tsql_Sql Server 2012 - Fatal编程技术网

Sql server T-SQL删除“重复/不感兴趣”的数据行

Sql server T-SQL删除“重复/不感兴趣”的数据行,sql-server,tsql,sql-server-2012,Sql Server,Tsql,Sql Server 2012,我提供了以下一组数据样本 ID Status Code Type ModDate 1234 1 1 AB 1995-04-01 1234 1 1 CD 1998-08-31 1234 1 1 AB 2003-08-31 1234 1 NULL AB 2008-11-08

我提供了以下一组数据样本

ID         Status  Code   Type       ModDate
1234       1       1      AB         1995-04-01
1234       1       1      CD         1998-08-31
1234       1       1      AB         2003-08-31
1234       1       NULL   AB         2008-11-08
1234       1       2      AB         2013-11-09
1234       1       1      EF         2013-11-18
...
由于必须在某种时间线上查看这些数据,因此我只想从数据库中阅读以下内容,因为只有类型更改才有意义:

ID         Status  Code   Type       ModDate
1234       1       1      AB         1995-04-01
1234       1       1      CD         1998-08-31
1234       1       1      AB         2003-08-31
1234       1       1      EF         2013-11-18
...
如何做到这一点?我试图对数据进行分区并给出一些行号,但由于类型是分组的,这让我很头疼

SELECT
    ID, Status, Code, Type, ModDate,
    MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate,
    MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate,
    ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber
FROM Data
输出:

ID         Status  Code   Type     ModDate       MinModDate    MaxModDate   RowNumber
1234       1       1      AB       1995-04-01    1995-04-01    2013-11-09   1
1234       1       1      CD       1998-08-31    1998-08-31    1998-08-31   1
1234       1       1      AB       2003-08-31    1995-04-01    2013-11-09   2
1234       1       NULL   AB       2008-11-08    1995-04-01    2013-11-09   3
1234       1       2      AB       2013-11-09    1995-04-01    2013-11-09   4
1234       1       1      EF       2013-11-18    2013-11-18    2013-11-18   1
...
预期产出:

ID         Status  Code   Type     ModDate       MinModDate    MaxModDate   RowNumber
1234       1       1      AB       1995-04-01    1995-04-01    2013-11-09   1
1234       1       1      CD       1998-08-31    1998-08-31    1998-08-31   1
1234       1       1      AB       2003-08-31    1995-04-01    2013-11-09   1
1234       1       NULL   AB       2008-11-08    1995-04-01    2013-11-09   2
1234       1       2      AB       2013-11-09    1995-04-01    2013-11-09   3
1234       1       1      EF       2013-11-18    2013-11-18    2013-11-18   1
...

不使用游标可以轻松实现这一点吗?

如果我理解正确,您只需要包装原始SQL:

SELECT ID, Status, Code, Type, ModDate FROM 
(
SELECT
    ID, Status, Code, Type, ModDate,
    MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate,
    MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate,
    ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber
FROM Data
) t
WHERE ModDate=MinModDate

对数据进行分区是您想要的,您只需要按类型进行分区,因为这是您感兴趣的唯一变化。您还需要添加ROW_NUMBER函数以过滤所需的行。这里有一个更新的查询

;WITH cte AS
(
    SELECT  ID, [Status], Code, [Type], ModDate
            ,rn = ROW_NUMBER() OVER (PARTITION BY ModDate ORDER BY ModDate)
    FROM    #data
)
SELECT  ID, [Status], Code, [Type], ModDate
FROM    cte
WHERE   rn = 1
ORDER   BY ModDate, [Type]

既然您使用2012,那么这应该可以:

SELECT ID, Status, Code, Type, ModDate FROM 
(
SELECT
    ID, Status, Code, Type, ModDate,
    lag(type,1) OVER (ORDER BY ID, moddate) prevtype
FROM data
)t WHERE type<>ISNULL(prevtype,'')

如果按ID和类型进行分区,那么为什么预期输出的第二、第三和第四行不会得到1、2、3行编号?该分区将在TYPE=AB的所有行上工作,并随后应用排序。这就是为什么第三行的RowNumber=2,而不是1,但这很好,因为我可以按RowNumber=1oh进行筛选,您可以按相同的顺序放置RowNumber。明白了。您使用的是sql server 2012吗?是的,sql server 2012与此语句一起使用,包含数据1234 1 AB 2003-08-31的行与此语句一起丢失,包含数据1234 1 AB 2003-08-31的行丢失如果您感兴趣的是Type by Mod,为什么要包含该AB行?根据数据还不清楚。我想在时间轴上显示类型列中的更改,当然可以将类型更改回以前的值,也可以使用相同的值再次保存记录。我试着忽略这些相同的值。我明白了。那么时间线过滤器是什么?如果同一天有两个相同类型的条目呢?然后,您是否需要查看ModDate的秒数并获取最近的秒数?为了简化,我删除了模式日期的时间部分,但它是一个日期时间类型的列现在第一行缺少1234 1 AB 1995-04-01。是因为在这种情况下没有前一行吗?我在我的机器上测试了它,第一行就在那里。isnullprevtype应该在没有前一行时进行保护。内部选择是正确的,但我需要修改prevType的外部WHERE语句为NULL或类型prevType。我接受你的回答,认为这对解决我的问题最有帮助。你可以使用WHERE-ISNULLType,PrevType-notnull来避免关心Type是否是字符串