【问题标题】:How to Finding Random records which are not available in the table after deleted ?is it possible to find out?删除后如何查找表中不可用的随机记录?是否可以找出?
【发布时间】:2021-05-31 10:38:15
【问题描述】:

我有一个名为 Student 的表,表列是 Id(身份密钥)和学生姓名。它有 100 条记录,从 1 到 100。我从学生表中随机删除了 5 条记录。现在该表只有 95 条记录。我如何获得逻辑表中没有 5 个 id 的内容。任何人都可以帮助找出正确的查询吗? 我尝试通过获取记录来编写查询,如果任何记录与记录不匹配,则循环中的每个记录 id 都会增加“1”,然后循环将继续直到最后一条记录第 100 条。面试官说这不是正确的方法,并没有告诉无论如何要找出来。我很困惑这是否可能。

【问题讨论】:

  • 如果他们不在那里,那么您将如何找到他们?您是否有其他信息来源来说明应该有什么?还是一些计算或逻辑?请edit您的问题并澄清
  • 你需要在你的表之间做一个左连接作为数字表,然后只过滤不匹配的数字
  • 我只有一张桌子。
  • 这确实 假设 ID 值之间没有间隙,@Sergey 和 IDENTITY(OP 似乎说他们正在使用)并不能保证那。实际上,除非您在“随机”删除它们时存储 DELETE 的行的值,否则您不会知道您删除了什么。
  • 好的。谢谢@Larnu

标签: sql sql-server


【解决方案1】:

您将使用output 子句:

declare @ids table (id int);

delete s
    output deleted.id into @ids
    from student s
    where . . .;

select *
from @ids;

【讨论】:

    【解决方案2】:

    它可以工作,但不适用于第一个 ID

    select s1.id+1  from student s1
    left join student s2 on s1.id = s2.id +1
    where s2.name is null 
    

    它适用于第一个 ID,不适用于最后一个 ID

    
    select s1.id-1  from student s1
    left join student s2 on s1.id-1 = s2.id 
    where s2.name is null 
    

    【讨论】:

      【解决方案3】:

      我认为问题是找到过去从表中删除的标识值,而不是关于如何在运行时将 id 输出到另一个表,同时它们被删除。

      如果您想从表中找出丢失的身份,请使用:

      ;WITH Missing (missnum, maxid)
      AS
      (
       SELECT 1 AS missnum, (select IDENT_CURRENT('Your_Table'))
       UNION ALL
       SELECT missnum + 1, maxid FROM Missing
       WHERE missnum < maxid
      )
      SELECT missnum
      FROM Missing
      LEFT OUTER JOIN Your_Table tt on tt.id = Missing.missnum
      WHERE tt.id is NULL
      OPTION (MAXRECURSION 0); 
      

      想法是使用递归 CTE 生成一个包含所有标识值的表,然后与删除了 id 的表进行左连接。

      如果您想在运行时输出被删除语句删除的行,那么上面的@Gordon Linoff 解决方案是正确的。

      【讨论】:

        【解决方案4】:

        如果我正确理解您的查询,您可以:

        1. 使用 CTE 列出给定范围内的所有 ID
        2. 从 CTE 中选择所有在您的表中不存在的 ID
        WITH N(V) AS (
          SELECT 1 
          UNION ALL
          SELECT V + 1 FROM N
          WHERE V < 100
        )
        SELECT *
            FROM N
            where V not in (select id from your_table)
        

        我注意到它是否是超级优雅的解决方案并涵盖所有可能的场景,但应该在大多数典型情况下完成工作。

        【讨论】:

          【解决方案5】:

          试试这样的:

          1. 在删除之前复制您的 Student
          2. 随机删除进程
          3. 然后尝试:
            SELECT    * 
            FROM      Student 
            EXCEPT 
            SELECT    * 
            FROM      StudentDuplicated
            

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-08-18
            • 1970-01-01
            • 2014-01-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多