Rechercher le numéro précédent dans la colonne qui ne manque pas dans une séquence

Aug 18 2020

J'ai un tableau avec une colonne qui devrait contenir des nombres dans une séquence complète, pour plus de simplicité, nous dirons 101 à 110. Cependant, ce tableau repose sur des informations peu fiables à saisir manuellement, donc les nombres dans la séquence sont manqués. Il y a aussi une colonne de date dans le même tableau à laquelle je dois me référer, plus à ce sujet dans un instant. J'ai été mis au défi de trouver tous les numéros de séquence manquants ainsi que le numéro de séquence précédent qui a été entré, la date à laquelle il a été entré, et le numéro de séquence suivant avec la date à laquelle il a été entré. Trouver les numéros de séquence manquants est simple, c'est obtenir les enregistrements précédents et suivants pertinents avec lesquels je me bats. Donc, si mes données ressemblaient à ceci;

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>

Mon jeu de résultats ressemblerait à quelque chose comme;

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>

Mais sans la colonne de notes, c'est juste là pour plus de clarté.

Je peux obtenir une réponse, mais le SQL est tellement énorme et peu maniable qu'il est aussi bon qu'inutile. Merci.

Réponses

2 GMB Aug 18 2020 at 21:01

Si vous voulez une ligne par espace, vous pouvez utiliser les fonctions de fenêtre:

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

D'un autre côté, si vous avez des nombres manquants consécutifs et que vous voulez une ligne pour chacun, vous avez besoin d'une sorte de récursivité:

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