Jump to content
AnaJulia

[problema] duvida com function

Recommended Posts

AnaJulia

Olá, minha duvida é a seguinte tenho q fazer uma function que imprime o somatório da diferença entre as direções do vento. Considere que a tabela esteja ordenada por data em ordem ascendente, como começo??

create database bded;
create table bded.tbTemp(
dataLeitura date primary key not null,
temperatura float(3,1),
direcaoVento float(4,1)
);
insert into bded.tbTemp values
('2009-08-12','15.2','316.7'),
('2009-08-11','16.8','311.8'),
('2009-08-10','15.5','84.4'),
('2009-08-09','24.9','199.4'),
('2009-08-08','25.9','185.8'),
('2009-08-07','26.8','194.8'),
('2009-08-06','27.0','203.3'),
('2009-08-05','25.0','286.9'),
('2009-08-04','23.4','308.6'),
('2009-08-03','20.6','55.8'),
('2009-08-02','23.8','61.2'),
('2009-08-01','24.6','288.6');
create table bded.tbRegistro (
idRegistro integer unsigned not null auto_increment,
operacao enum('insert', 'update', 'delete') not null,
dataHorario datetime not null,
usuario varchar(80) not null,
primary key(idRegistro)
);
create table bded.tbBackup(
idBackup integer unsigned not null auto_increment,
dataLeitura date not null,
temperatura float(3,1),
direcaoVento float(4,1),
primary key(idBackup)
);

E saida seria assim

z05j.png

Qualquer ajuda sera bem vinda, obrigada

Share this post


Link to post
Share on other sites
AnaJulia

por exemplo vc tem as temperaturas 28,31,29 a diferença seria, 31-28=3 e 29-31=2, pra fazer tem q usar um cursor.

Edited by AnaJulia

Share this post


Link to post
Share on other sites
AnaJulia

o que consegui fazer, mas fica dando erro:

delimiter $
drop function if exists exer2 $
create function exer2() returns float
deterministic
begin
declare diferenca float default 0;
    declare dirVento float default 0;
    declare fim boolean default false;
    declare c cursor for
                    select direcaoVento
    from tbTemp;
    declare continue handler for not found
                    set fim = true;
    select direcaoVento from tbTemp into dirVento;
    open c;
        while fim <> true do
            fetch c into diferenca;
            if fim <> true then
                    set diferenca= diferenca - dirVento;
            end if;
        end while;
    close c;
    return diferenca;
end$
delimiter ;
#testar function
select round(exer2(),2);

---edit -outra forma q fiz, mas não ta funcionando o cursor ¬

delimiter $
drop function if exists exer2 $
create function exer2() returns float
deterministic
begin

declare diferenca float default 0;
    declare cont int default 0;
    declare fim boolean default false;
    declare c cursor for
                    select direcaoVento
    from tbTemp;
    declare continue handler for not found
                    set fim = true;
    open c;
        while fim <> true do
            fetch c into diferenca;
            if fim <> true then
                    set cont = diferenca - cont ;

            end if;
        end while;
    close c;
return diferenca;
end$
delimiter ;

O que vcs acham q pode arrumar?

Edited by Rui Carlos
GeSHi

Share this post


Link to post
Share on other sites
Rui Carlos

Acho que nunca usei cursores antes em MySQL, mas não estou a ver onde é que estás a calcular diferenças entre duas direcções. Penso que precisas de manter duas direcções em variáveis (a "actual" e a "anterior"), para calculares a diferença, que depois adicionas a um acumulador. Penso que o teu segundo exemplo está mais próximo do que precisas do que o primeiro.


Para referência, a solução com uma query "normal" podia ser algo como:

select sum((day0.direcaoVento - day1.direcaoVento)) as tdiff
from tbTemp as day0 inner join tbTemp as day1
	on datediff(day0.dataLeitura, day1.dataLeitura) = 1

(Acho que fazia mais sentido haver ali um ABS a seguir ao SUM, mas só assim é que dá o resultado esperado.)

Edited by Rui Carlos

Share this post


Link to post
Share on other sites
HappyHippyHippo

Solução 1 : TOTAL = SUM(X(n) - X(n-1))

delimiter $
DROP FUNCTION IF EXISTS solucao1 $
CREATE FUNCTION solucao1() RETURNS FLOAT
deterministic
BEGIN

   DECLARE v_sum FLOAT DEFAULT 0;
   DECLARE v_prev FLOAT DEFAULT 0;
   DECLARE v_current FLOAT DEFAULT 0;
   DECLARE v_first BOOLEAN DEFAULT TRUE;
   DECLARE v_end BOOLEAN DEFAULT FALSE;
   DECLARE v_cursor CURSOR FOR SELECT direcaoVento FROM tbTemp ORDER BY dataLeitura ASC;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_end = TRUE;

   OPEN v_cursor;
   read_loop: LOOP
       FETCH v_cursor INTO v_current;

       IF v_end THEN
           LEAVE read_loop;
       END IF;

       IF v_first = TRUE THEN
           SET v_first = FALSE;
       ELSE
           IF v_end <> TRUE THEN
               SET v_sum = v_sum + v_current - v_prev;
           END IF;
       END IF;
       SET v_prev = v_current;
   END LOOP;

   CLOSE v_cursor;
   RETURN v_sum;
END$
delimiter ;

Solução 2 : TOTAL = X(n) - X(0)

delimiter $
DROP FUNCTION IF EXISTS solucao2 $
CREATE FUNCTION solucao2() RETURNS FLOAT
deterministic
BEGIN

   DECLARE v_start FLOAT DEFAULT 0;
   DECLARE v_current FLOAT DEFAULT 0;
   DECLARE v_first BOOLEAN DEFAULT TRUE;
   DECLARE v_end BOOLEAN DEFAULT FALSE;
   DECLARE v_cursor CURSOR FOR SELECT direcaoVento FROM tbTemp ORDER BY dataLeitura ASC;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_end = TRUE;

   OPEN v_cursor;
   read_loop: LOOP
       FETCH v_cursor INTO v_current;

       IF v_end THEN
           LEAVE read_loop;
       END IF;

       IF v_first = TRUE THEN
           SET v_first = FALSE;
           SET v_start = v_current;
       END IF;
   END LOOP;

   CLOSE v_cursor;
   RETURN v_current - v_start;
END$
delimiter ;

Solução 3 : a mesma que a anterior mas sem o uso de cursores ... (fica para praticares)

Edited by HappyHippyHippo
  • Vote 1

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.