【问题标题】:Find previous number in column that is not missing from a sequence查找序列中未丢失的列中的前一个数字
【发布时间】:2020-12-07 17:32:01
【问题描述】:

我有一个表,其中的列应包含完整序列中的数字,为简单起见,我们将说 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, th, 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 是如此庞大和笨重,它和无用一样好。谢谢。

【问题讨论】:

  • 这好像是关于html和css的问题,为什么这个标签是sql和oracle?
  • 因为问题是关于 oracle 数据库上的 sql 以获得我所需的结果集。 html 只是因为这是我能看到的显示表格以便于阅读的唯一方法。如果我可以做不同的事情,请告诉我,我会编辑问题。
  • 您可以将结果复制并粘贴到代码中,这是可读的。但是如果你提供 ddl 和一些 dml 和预期的结果(可以只是粘贴)会容易得多

标签: sql oracle datetime window-functions gaps-and-islands


【解决方案1】:

如果你想每个间隔一行,那么你可以使用窗口函数:

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(seq_no) over(order by date_input) lag_seq_no,
           lag(date_input) over(order by date_input) lag_date_input
        from mytable t
    ),
    cte (seq_no, date_input, lag_seq_no, lag_date_input) as (
        select seq_no, date_input, lag_seq_no + 1, lag_date_input
        from data
        where seq_no > lag_seq_no + 1
        union all
        select seq_no, date_input, lag_seq_no + 1, lag_date_input
        from cte
        where seq_no > lag_seq_no + 1
) 
select 
    lag_seq_no missing_seq_no,
    lag_date_input last_date_input,
    date_input next_date_input
from cte
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2020-05-13
    • 2020-05-16
    • 1970-01-01
    • 2011-11-11
    相关资源
    最近更新 更多