SQL异常查询,查找连续元素之间的最大增量

时间:2012-11-28 08:23:13

标签: mysql sql

我遇到了一个有趣的问题。 我有一张工人'的表和他们的访问日。这是转储:

CREATE TABLE `pp` (
  `id` int(11) DEFAULT '1',
  `day` int(11) DEFAULT '1',
  `key` varchar(45) NOT NULL,
 PRIMARY KEY (`key`)
) 

INSERT INTO `pp` VALUES 
   (1,1,'1'),
   (1,20,'2'),
   (1,50,'3'),
   (1,70,'4'),
   (2,1,'5'),
   (2,120,'6'),
   (2,90,'7'),
   (1,90,'8'),
   (2,100,'9');

所以我需要找到至少错过50天以上的工人。例如,如果工人在第5天,第95天,第96天,第97天访问,如果我们查看增量,我们可以看到最大的增量(90)超过50,所以我们应该将这个工人包括在结果中。 问题是如何有效地找到不同工人的访问之间的增量?

我甚至无法想象如何使用mysql表作为后续数据数组。

因此,我们需要为不同的工作人员分隔日期值,对它们进行排序,然后为每个工作者找到最大增量。但是怎么样?有没有办法,例如,在sql中枚举排序数组?

3 个答案:

答案 0 :(得分:2)

尝试此查询 -

<强>编辑:

SELECT t.id, t.day1, t.day2 FROM (
  SELECT p1.id, p1.day day1, p2.day day2 FROM pp p1
    JOIN (SELECT * FROM pp ORDER BY day) p2
      ON p1.id = p2.id AND p1.day < p2.day
   GROUP BY p1.id, p1.day
  )  t
GROUP BY t.id
HAVING MAX(day2 - day1) >= 50

答案 1 :(得分:1)

这是我用来解决这些问题的一种方式:

SELECT distinct t3.id  FROM
(SELECT t1.id, t1.day, MIN(t2.day) nextday
FROM pp t1
JOIN pp t2 ON t1.id=t2.id AND t1.day<t2.day
GROUP BY t1.id, t1.day
HAVING nextday-t1.day >50) t3

编辑此版本略胜一筹) 这将找到存在delta的所有ID&gt; 50.(我认为这就是你所追求的)

要查看它是否有效:SQL fiddle

要查找最大增量:

SELECT t3.id, MAX(t3.nextday-t3.day)  FROM
(SELECT t1.id, t1.day, MIN(t2.day) nextday
FROM pp t1
JOIN pp t2 ON t1.id=t2.id AND t1.day<t2.day
GROUP BY t1.id, t1.day) t3
GROUP BY t3.id

背后的逻辑是找到“下一个”项目,无论这意味着什么。由于这是一个有序属性,下一个项目可以定义为具有值大于检查值的那些行中的最低值...然后将“下一个”值连接到原始值,将delta,conpute,并仅返回适用的那些。如果您还需要其他列,只需在外部选择JOIN到原始表。

我不确定这是否是关于perfirmance的最佳解决方案,但我只针对一次性报告编写查询,我可以用这些查询运行一段时间。

虽然存在一个语义错误,但可能会出现:如果有人在第1天,第2天和第3天出现,但从未出现,则不会发现缺席。为了解决这个问题,您可以添加一个特殊行,其中UNION选择表格,指定所有ID的明天的日期计数,但这会使此查询恶心,不会尝试将其写下来。 ..

答案 2 :(得分:1)

这也可以是一个解决方案:

select distinct pp.id
from pp
where pp.day-(select max(day)
              from pp pp2
              where
                pp2.id=pp.id and
                pp2.day<pp.day)>=50

(由于日期不按密钥排序,我不会搜索之前的密钥,而是搜索当天之前的最大日期)