Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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查询-保留组的第一个和最后一个唯一记录_Sql_Sql Server_Duplicates - Fatal编程技术网

SQL Server查询-保留组的第一个和最后一个唯一记录

SQL Server查询-保留组的第一个和最后一个唯一记录,sql,sql-server,duplicates,Sql,Sql Server,Duplicates,我们正在尝试删除并排列系统每日提要中提供的表中的数据。示例数据当然不是实际的产品,但清楚地表示了概念 每日插页: 数据每天导入到表中,这些表不断更新产品的状态 每日状态更新告诉我们产品上市的时间、当前上市的时间以及上市的最后日期 经过一段{X}时间后,我们可以规范化数据 清理和排名: 我们现在正在尝试删除组中介于第一个值和最后一个值之间的值的重复记录 我们还希望为表示该组中第一个和最后一个唯一值的记录设置标识符 样本数据: 我发现照片是最简单的方式来显示数据,显示什么是需要的和不需要的-我希望

我们正在尝试删除并排列系统每日提要中提供的表中的数据。示例数据当然不是实际的产品,但清楚地表示了概念

每日插页:

  • 数据每天导入到表中,这些表不断更新产品的状态
  • 每日状态更新告诉我们产品上市的时间、当前上市的时间以及上市的最后日期
  • 经过一段{X}时间后,我们可以规范化数据
  • 清理和排名:

  • 我们现在正在尝试删除组中介于第一个值和最后一个值之间的值的重复记录

  • 我们还希望为表示该组中第一个和最后一个唯一值的记录设置标识符

  • 样本数据:

    我发现照片是最简单的方式来显示数据,显示什么是需要的和不需要的-我希望这使它更容易,而不是迟钝

    在样本数据中:

    • “ridgerapp”我们想保留2017年3月12日和2017年6月12日的记录
    • “ridgerapp”我们想删除上述日期之间的记录
    • “ridgerapp”我们还想设置/更新2017年12月3日和2017年12月6日的记录,作为第一次和最后一次出现-类似于-
    • 更新表格集03/12/17=0(第一个),06/12/17=1(最后一个)

    • “sierra”只是另一个扩展数据样本,我们希望保留2016年6月12日和2016年11月12日的记录

    • “sierra”删除2016年6月12日至2016年11月12日之间的记录
    • “sierra”将2016年6月12日和2016年11月12日记录的状态/等级更新为第一个和最后一个事件
    • 更新表格集12/06/16=0(第一个),12/11/16=1(最后一个)
    结论:

    使用伪代码,这是总体目标:

    • 在表中选择不同的记录(使用id、名称、颜色、值作为唯一标识符)
    • 对于每个组中的记录,请查看历史记录,并找到顶部和底部日期
    • 删除每个组的顶部和底部日期之间的记录
    • 对于每个组中的值,使用0和1的状态/等级(字段名称为等级)更新历史记录
    • 使用样本数据,结果将结束
    更新的表值:

     23  ridgerapp  blue    25  03/12/17    0
     23  ridgerapp  blue    25  06/12/17    1
     57  sierra     red     15  12/06/16    0
     57  sierra     red     15  12/11/16    1
    

    我会使用
    CTE
    row\u number()
    窗口函数来查找每个组的第一行和最后一行,然后更新它

    您没有指定是什么使一个组成为一个组,因此我仅根据
    ID
    来确定。如果希望组是一组列,即
    ID
    Color
    Value
    ,则只需将这些列添加到
    分区依据
    列表中即可。对于样本数据,结果是相同的,但不同的样本数据会有不同的结果

    请注意,我没有包括sierra组的确切行,因为我想向您展示它如何处理重复的
    历史
    日期

    declare @table table (id int, [name] varchar(64), color varchar(16), [value] int, history date)
    insert into @table
    values
    (23,'ridgerapp','blue',25,'20170312'),
    (23,'ridgerapp','blue',25,'20170325'),
    (23,'ridgerapp','blue',25,'20170410'),
    (23,'ridgerapp','blue',25,'20170610'),
    (23,'ridgerapp','blue',25,'20170612'),
    
    (57,'sierra','red',15,'20161206'),
    (57,'sierra','red',15,'20161208'),
    (57,'sierra','red',15,'20161210'),
    (57,'sierra','red',15,'20161210')   --notice this is a duplicate row
    
    ;with cte as(
    select 
        *
        ,fst = row_number() over (partition by id order by history asc)
        ,lst = row_number() over (partition by id order by history desc)
    from @table
    )
    
    delete from cte
    where fst !=1 and lst !=1
    
    select 
        *
        ,flag = case when row_number() over (partition by id order by history asc) = 1 then 0 else 1 end
    from @table
    
    返回

    +----+-----------+-------+-------+------------+------+
    | id |   name    | color | value |  history   | flag |
    +----+-----------+-------+-------+------------+------+
    | 23 | ridgerapp | blue  |    25 | 2017-03-12 |    0 |
    | 23 | ridgerapp | blue  |    25 | 2017-06-12 |    1 |
    | 57 | sierra    | red   |    15 | 2016-12-06 |    0 |
    | 57 | sierra    | red   |    15 | 2016-12-10 |    1 |
    +----+-----------+-------+-------+------------+------+
    

    在解释第一个问题、使用样本数据和预期输出方面做得很好。对于以后的帖子,请尝试以DDL和DML的形式给出示例数据,就像我在下面的回答中所做的那样,并以文本而不是图像的形式给出结果:)感谢您的建议和帮助,这里显然是新的。我有罪。非常感谢您的建议!啊,太谢谢你了!在你的回答和我提出的问题中,对细节的关注超出了你的想象。这正是{正是!}我想做的事,我的洛特利投票支持答案是正确的,但没有移动指针。但这是100%正确的。再次感谢-jNo problem@seligtech您可以选择正确答案的复选标记。最美好的祝福。