Hive / MySQL - нужна помощь для увеличения последовательных 1 во входном столбце - PullRequest
1 голос
/ 02 апреля 2019

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

ID   Input_column          Expected Output Column     date_start   date_end
 1A       0                      0                      ts1            ts2
 1A       1                      0                      ts4            ts6 
 2B       0                      0                      ts7            ts9
 2B       1                      1                      ...            ...
 2B       1                      1                      ...            ...
 2B       0                      0                      ...            ...
 2B       0                      0                      ...            ...
 2B       1                      2                      ...            ...
 2B       1                      2                      ts11           ts15
 2B       1                      2                      ts20           ts22 
 2B       0                      0                      ...            ... 
 3C       0                      0                      ...            ... 
 3C       1                      3                      ...            ...
 3C       1                      3                      ...            ...  
 3C       1                      3
 3C       0                      0
 3C       1                      4
 3C       1                      4
 3C       0                      0
 3C       0                      0                      ts50            ts53
 3C       1                      0                      tsxx            tsyy
 3C       0                      0                      tsyy            tsnn

Я пробовал ответы ниже, но это не сработало, как ожидалось.

1) hive, как увеличить значения, относящиеся к условию?

2) Запрос Hive, генерирующий идентификаторы для последовательности строк, соответствующих условию

Может кто-нибудьпомочь мне в решении этой проблемы?

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Решение Pure SQL с использованием оконных функций, без объединений, протестировано на Hive с примером данных:

with your_table as --use your table instead of this CTE
( 
select stack(23,
  1 , 0,        
  2 , 1,        
  3 , 0,        
  4 , 1,        
  5 , 1,        
  6 , 0,        
  7 , 0,        
  8 , 1,        
  9 , 1,        
  10, 1,        
  11, 0,        
  12, 0,        
  13, 1,        
  14, 1,        
  15, 1,        
  16, 1,        
  17, 0,        
  18, 1,        
  19, 1,        
  20, 0,        
  21, 0,        
  22, 1,        
  23, 0
) as ( ID ,Input_column  )  
) --use your table instead of this CTE

select s.id, s.input_column, 
       case when grp_id is null then 0 
            else dense_rank() over (partition by (grp_id is null) order by grp_id) 
         end as output_column
       from

(
select s.id, s.input_column, 
       case when same_group_flag then   --distribute same grp_id across same group
       max(grp_id) over(order by id rows between unbounded preceding and current row ) 
       end as grp_id
from
(
select s.id, s.input_column , 
       case when input_column=1 and (prev_value!=1 or prev_value is null) and next_value=1 then id end as grp_id,
       input_column=1 and (prev_value=1 or next_value=1)                                               as same_group_flag

       from
(       
select id, input_column, 
       lead(input_column) over(order by id) next_value,
       lag(input_column) over(order by id) prev_value
  from your_table
)s
)s
)s
order by id;

Результат:

id  input_column  output_column
1       0       0
2       1       0
3       0       0
4       1       1
5       1       1
6       0       0
7       0       0
8       1       2
9       1       2
10      1       2
11      0       0
12      0       0
13      1       3
14      1       3
15      1       3
16      1       3
17      0       0
18      1       4
19      1       4
20      0       0
21      0       0
22      1       0
23      0       0
Time taken: 226.407 seconds, Fetched: 23 row(s)

Результат в точности соответствует ожидаемому.Также взгляните на очень похожий вопрос: https://stackoverflow.com/a/55336802/2700344

0 голосов
/ 02 апреля 2019

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

delimiter $$
drop procedure if exists test2 $$
create procedure test2()
begin
declare v_count int default 1 ;
declare v_loop int default 1 ;
declare v_i int;
declare v_j int;
declare v_id int;
declare work cursor for select sr_no,lead(sr_no,1)over(order by id) as sr_no2,id  from tmp;

 SET @row_number:=0;
 SET @db_names:='';
 drop temporary table if exists tmp;
 create TEMPORARY table tmp  as 
select id,sr_no from 
(select id,
@row_number:= CASE WHEN (value1 and value2 =1) or @db_name=1  THEN 1 ELSE 0 END AS sr_no ,
@db_name:=  (CASE WHEN (value1 and value2 =1)  THEN 1 ELSE 0 END)
from 
(SELECT t2.id, t2.value1 as value2,t1.value1
FROM t4 t1
inner join t4 t2
on (t1.id = t2.id+1))A)d;


 OPEN work;
 work: LOOP 
 FETCH work INTO v_i,v_j,v_id;

 if ((v_i and v_j = 1) or v_i=1  ) then 
    SET v_loop=v_loop+1;
     if (v_loop > 0)then
       update tmp  SET sr_no= v_count   where id=v_id;
    end if;
 else 
     if(v_loop > 1)then
        SET v_count=v_count+1;
        SET v_loop =0;
     else 
        SET v_loop =0;
     end if ;  
 end if;


 END LOOP work;

 CLOSE work;


end $$
delimiter $$

запустить этот sp и затем просто использовать

select * from tmp for your output
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...