Ведущая функция для отсутствующих записей - PullRequest
0 голосов
/ 01 мая 2019

Я использую запрос ниже

 select  id,
         number_sequ,
         startvalue
         lead(startvalue,1,0) over (partition by id order by number_sequ) AS End_value
 from mytable

для заполнения следующего вывода

id             number_sequ   startvalue       End_value
----            -----       ----------       -----------
AAA             1             30              20
AAA             2             20              10
AAA             4             10              15
AAA             5             15              0
BBB             1             12              23
BBB             3             23              34
BBB             4             34              0

Но в последовательности отсутствуют записи

id         number_sequ   startvalue       End_value
----         -----       ----------       -----------
AAA          3           
BBB          2

Я пробовал разные способы, чтобы найти пропущенные числа в последовательности и попытаться вставить с 0 значениями. после этого я могу использовать ведущую функцию. невозможно найти эффективный способ

INSERT INTO mytable (id, number_sequ, startvalue)
    select id ,number_sequ ,'0'
    from mytable
    where (some condition to specify missing data)

Может ли кто-нибудь помочь мне решить вышеуказанную проблему.

Ответы [ 3 ]

0 голосов
/ 02 мая 2019

Если пропущенные значения всегда находятся между существующими значениями, вы можете найти пропуски, используя JavaScript UDTFs Снежинки

Например, вот функция, которая находит пропуски в последовательности, изатем мы используем его для генерации «пустых» строк:

create or replace table x(id int, seq int, startVal int) as select * from
values(1,1,11),(1,2,12),(1,4,14),(2,2,22),(2,5,25);


CREATE OR REPLACE FUNCTION find_gaps(SEQ float)
RETURNS TABLE (GAP float)
LANGUAGE JAVASCRIPT
AS '
  {
    initialize: function(argumentInfo, context) {
      this.lastRow = null;
    },
    processRow: function (row, rowWriter, context) {
      let curRow = row.SEQ;
      if (this.lastRow == null || this.lastRow + 1 == curRow) {
        this.lastRow = curRow;
      } else {
        while (this.lastRow + 1 < curRow) {
          this.lastRow++;
          rowWriter.writeRow({GAP: this.lastRow});
        }
      }
    }
  }'
;

select id, seq, startVal from x 
union all  
select id, gap, 0 from x,     
  table(find_gaps(seq::float) 
    over (partition by id order by seq));

----+-----+----------+
 ID | SEQ | STARTVAL |
----+-----+----------+
 1  | 1   | 11       |
 1  | 2   | 12       |
 1  | 4   | 14       |
 2  | 2   | 22       |
 2  | 5   | 25       |
 2  | 3   | 0        |
 2  | 4   | 0        |
 1  | 3   | 0        |
----+-----+----------+

Вы также можете использовать варианты этой функции, например, если вам известен диапазон значений для идентификатора, просто введите его ожидаемый минимум / максимум.Кроме того, вам может понадобиться что-то особенное, если ваши входные данные содержат значения NULL (но тогда - каким должен быть результат?:))

0 голосов
/ 02 мая 2019

Помимо предложенных решений, если вы все еще хотите придерживаться функции Lead,

Функция Lead анализирует данные, у которых есть значения, результат может иметь нулевые значения на основе раздела, но данные, которые он использует дляанализы должны иметь значения.На мой взгляд, то, что вы сделали, правильно включить недостающую последовательность в ваш результат.

http://www.mysqltutorial.org/mysql-window-functions/mysql-lead-function/

0 голосов
/ 01 мая 2019

Вы можете получить пропущенные значения следующим способом: сгенерируйте все возможные значения, а затем отфильтруйте существующие.

select i.id, n.n, 0 as start_value
from (select id, min(number_seq) as min_ns, max(number_seq) as max_ns
      from mytable
      group by id
     ) i join
     (select row_number() over (partition by number_seq) as n
      from mytable
     ) n
     on n.n <= i.max_ns left join -- just a bunch of numbers
     mytable t
     on t.id = i.id and
        t.number_seq = n.n 
where t.id is null;

Вы можете вытолкнуть insert перед select, чтобы вставить эти значения в вашу таблицу.

Обратите внимание, что при этом генерируются необходимые порядковые номера с использованием исходных данных. Поэтому предполагается, что в вашей таблице достаточно строк для нужных вам чисел.

...