在序列中不丢失的列中找到上一个数字

问题描述

我有一个表,该表的列应包含完整序列中的数字,为简单起见,我们将其称为101到110。但是,此表依赖于不可靠的信息来手动输入,因此序列中的数字会被遗漏。我需要在同一张表中还有一个日期列,稍后再介绍。我一直面临着查找所有缺少的序列号以及输入的上一个序列号,输入日期和下一个带有输入日期的序列号的挑战。查找丢失的序列号很简单,它正在获取我正在苦苦挣扎的相关上一个和下一个记录。所以如果我的数据看起来像这样;

table,th,td {
  border: 1px solid black;
  border-collapse: collapse;
}
<html>

<body>
  <table>
    <tr>
      <th>Seq No</th>
      <th>Date Input</th>
    </tr>
    <tr>
      <td>101</td>
      <td>01-JAN-20</td>
    </tr>
    <tr>
      <td>102</td>
      <td>05-JAN-20</td>
    </tr>
    <tr>
      <td>104</td>
      <td>07-JAN-20</td>
    </tr>
    <tr>
      <td>105</td>
      <td>08-JAN-20</td>
    </tr>
    <tr>
      <td>106</td>
      <td>09-JAN-20</td>
    </tr>
    <tr>
      <td>108</td>
      <td>10-JAN-20</td>
    </tr>
    <tr>
      <td>109</td>
      <td>11-JAN-20</td>
    </tr>
    <tr>
      <td>110</td>
      <td>12-JAN-20</td>
    </tr>
  </table>
</body>

</html>

我的结果集看起来像;

table,td {
  border: 1px solid black;
  border-collapse: collapse;
}
<html>
<body>
  <table>
    <tr>
      <th>Missing Seq No</th>
      <th>Previous Date</th>
      <th>Next Date</th>
      <th>Notes</th>
    </tr>
    <tr>
      <td>103</td>
      <td>05-JAN-20</td>
      <td>07-JAN-20</td>
      <td>Dates from found seq nos 102 and 104</td>
    </tr>
    <tr>
      <td>107</td>
      <td>09-JAN-20</td>
      <td>10-JAN-20</td>
      <td>Dates from found seq nos 106 and 108</td>
    </tr>
  </table>
</body>
</html>

但没有注释列,只是为了清楚起见。

我可以找到答案,但是sql是如此庞大且笨拙,它就像无用一样好。谢谢。

解决方法

如果每个间隙要排一行,则可以使用窗口功能:

select 
    lag_seq_no last_sequence_number,lag_date_input last_date_input,seq_no next_sequence_number,date_input next_date_input
from (
    select 
        t.*,lag(seq_no) over(order by date_input) lag_seq_no,lag(date_input) over(order by date_input) lag_date_input
    from mytable t
) t
where seq_no > lag_seq_no + 1

另一方面,如果您连续缺少数字,并且每个数字都想要一行,那么您需要某种递归:

with 
    data(seq_no,date_input,lag_seq_no,lag_date_input) as (
        select 
            t.*,lag(date_input) over(order by date_input) lag_date_input
        from mytable t
    ),cte (seq_no,lag_date_input) as (
        select seq_no,lag_seq_no + 1,lag_date_input
        from data
        where seq_no > lag_seq_no + 1
        union all
        select seq_no,lag_date_input
        from cte
        where seq_no > lag_seq_no + 1
) 
select 
    lag_seq_no missing_seq_no,date_input next_date_input
from cte
    

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...