如何根据应用于不同列的条件找到行差异

时间:2019-02-21 07:07:32

标签: sql

我有一个包含名称,日期和标志的数据集,该标志为正,负或中性。数据集按名称排序,然后按日期排序。我必须严格按照该顺序找到负号和正号的日期与每个人第一次发生日期之间的差异。例如,如果数据集看起来像

Aaron     5th Feb.       +
Aaron.    7th Feb.       -
Aaron.    10th Feb.      -
Aaron.    11th Feb.      +
Aaron.    15th. Feb.     -
Aaron.    20th Feb.      +

在这里,答案应该是1天(10日至11日)。因此查询应返回

Aaron.  1
Dave.   2
....    And so on

1 个答案:

答案 0 :(得分:0)

我设法通过MySQL函数实现了这一点:

这是示例表:

select * from tets;
+-------+---------------------+------+
| name  | date                | flag |
+-------+---------------------+------+
| aron  | 2019-02-05 00:00:00 | +    |
| aron  | 2019-02-07 00:00:00 | -    |
| aron  | 2019-02-10 00:00:00 | -    |
| aron  | 2019-02-11 00:00:00 | +    |
| aron  | 2019-02-15 00:00:00 | -    |
| aron  | 2019-02-20 00:00:00 | +    |
| dave  | 2019-02-04 00:00:00 | +    |
| dave  | 2019-02-06 00:00:00 | -    |
| dave  | 2019-02-08 00:00:00 | -    |
| dave  | 2019-02-10 00:00:00 | +    |
| dave  | 2019-02-11 00:00:00 | -    |
| dave  | 2019-02-12 00:00:00 | +    |
| rambo | 2019-01-06 00:00:00 | -    |
| rambo | 2019-01-08 00:00:00 | +    |
+-------+---------------------+------+

如果我对请求的理解正确,对于上述每个名称,您都希望查找其首次从“-”更改为“ +”的日期之间的差异[我们需要严格考虑“-”改为“ +”,而不是相反的方式]

因此,如下所示的函数应会为您提供结果:(请原谅变量的随机名称:))

delimiter ||
create  function dummy ()
returns text
begin
declare end_cursor int default 0;
declare i varchar(50);
declare b datetime;
declare c datetime;
declare d datetime;
declare e datetime;
declare ans int(11);
declare prt text default '';

DECLARE a cursor for select distinct(name) from tets;
DECLARE CONTINUE HANDLER FOR NOT FOUND set end_cursor=1;

open a;

read_loop: loop 
fetch a into i;
if end_cursor=1
then
LEAVE read_loop;
end if;

set b = (select min(`date`) from tets where name=i and flag='-');
set c = (select min(`date`) from tets where name=i and flag='+');

while b > c
do
set d = (select min(`date`) from tets where name=i and flag='+' and `date`!=c);
set c=d;

end while;

if exists (select `date` from tets where `date` > b and `date` < c)
then
set e = (select max(`date`) from tets where `date` > b and `date` < c);
set b = e;

set ans = datediff(c,b);

set prt = concat( prt,'For ',i,' the dates are ',b,' & ',c,' and the difference is ',ans,', ','\n');

else

set ans = datediff(c,b);

set prt = concat( prt,'For ',i,' the date are ',b,' & ',c,' and the difference is ',ans,', ','\n');

end if;

end loop read_loop;
close a;
return prt;
end;
||
delimiter ;

当我调用函数时:

mysql> select dummy() \G

dummy(): For aron the dates are 2019-02-10 00:00:00 & 2019-02-11 00:00:00 and         
the difference is 1, 
For dave the dates are 2019-02-08 00:00:00 & 2019-02-10 00:00:00 and the     
difference is 2, 
For rambo the date are 2019-01-06 00:00:00 & 2019-01-08 00:00:00 and the 
difference is 2,