选择在彼此日期范围内的连续行

Eni*_*say 4 mysql

有一个关联日期和名称的列表,我想选择:当日期之间的差异超过 1 个月时,名称具有多个日期的所有行。

例如:只有下面标有的条目 \*this*\

CREATE TABLE IF NOT EXISTS myTab (
    id          SERIAL PRIMARY KEY,     
    dateID      DATETIME DEFAULT 0,     
    name        VARCHAR(512)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO myTab 
    (dateID, name) 
VALUES
    ("20140811","Emmy"),    /*this*/
    ("20140922","Emmy"),    /*this*/
    ("20150920","Emmy"),    /*this*/
    ("20150922","Emmy"),
    ("20140722","Dave"),
    ("20140613","Stan"),
    ("20140622","Stan"),    /*this*/
    ("20151020","Stan"),    /*this*/
    ("20140305","Lora"),
    ("20140310","Lora");
Run Code Online (Sandbox Code Playgroud)

换句话说,标准是:

  • P artition按名称
  • Ø刻申日期
  • Ç ompare连续2行:IF diff > 1 MONTH THEN select both, ELSE skip

这是一个工作示例以及我基于SO 的另一个答案的尝试:

Rexester 工作示例和尝试

附加条件/提示/...

  • 具有相同名称的行不一定在另一个之后插入一次,使它们彼此间隔开+1 id。它们也不按日期插入。在上面的例子中,这样做只是为了可读性。在我真正的问题中,情况并非如此!
  • 在将您的建议应用于真实数据后,我注意到/*this_EXRA*/在上面的示例中添加了一个额外的条件。第 3stan行距第 2 行不到 1 个月,但使用第 4 行对其进行验证。因此,只有当它同时验证它们时才应该选择它。所以我想这意味着逐行循环并每次与上一个和下一个进行比较。

ype*_*eᵀᴹ 5

这个逻辑乍一看很简单,但要做好却相当复杂。

让我们先有一个可行的解决方案,然后再考虑性能。在reextester.com 上测试:

SELECT t.id, t.dateID, t.name 
FROM  myTab AS t
WHERE 
       ( SELECT b.dateID
         FROM myTab AS b
         WHERE t.name = b.name
           AND b.dateID < t.dateID
         ORDER BY b.dateID DESC
         LIMIT 1
       ) + INTERVAL 1 MONTH  <=  t.dateID    
    OR 
       t.dateID + INTERVAL 1 MONTH <= 
       ( SELECT b.dateID
         FROM myTab AS b
         WHERE t.name = b.name
           AND t.dateID < b.dateID
         ORDER BY b.dateID ASC
         LIMIT 1
       )
 ;
Run Code Online (Sandbox Code Playgroud)

关于效率:查询的性能会很差。索引(name, dateID, id)会有所帮助,但查询仍需要为表的每一行执行 2 个子查询。