2014-02-25 63 views
1

我有一个调度数据库,我想找一种方法来选择所有未来的约会,因为我们有很多客户自己翻书。我一直在寻找,但我无法找到一种方法来完成我想要的。如何在同一个表中找到相似的记录?

例如,如果我有以下几行,我希望能够选择那些具有相同语言,相隔15分钟的时间,并且名称共享> 70%的相同字符。

|Rec_id|Date_time  |Language|App_name | 
    |1  |2014-03-15 12:40|Spanish |Ricardo | 
    |2  |2014-03-15 12:45|Spanish |Ricerdu | 
    |3  |2014-03-16 12:45|Tongan |Tuaffu | 
    |4  |2014-03-17 12:45|Korean |Kim  | 
    |5  |2014-03-18 12:45|German |Biternof | 
    |6  |2014-03-18 12:32|German |Biterknof| 

从上面的数据,我需要的记录是1,2,5和6

+0

他们不重复,他们是不同的app_name? –

+0

他们不重复,但我们的客户不希望在我们安排2名员工可用时付费。这种情况一天发生数次,规模大得多。 –

+1

我也很想知道倒票的原因。有没有办法改善这个问题? –

回答

1

我想到的第一件事就是莱文斯坦但由于MySQL有没有它的原生支持 - 事情变得有点更复杂。

该解决方案没有经过优化或根本没有最好的解决方案,但我应该完成这项工作。

  • 我会创建一个新列,我们称之为“Duplicate_for”,DEFAULT NULL。
  • 我会为此表创建一个触发器:TRIGGER BEFORE INSERT。
  • 我会创建一个函数来计算两个字符串的Levenshtein距离。
  • 我会结合TRIGGER和Levenshtein以下查询。

触发+查询本身:

DELIMITER // 
CREATE TRIGGER `booking_before_insert` BEFORE INSERT ON `booking` FOR EACH ROW BEGIN 
    DECLARE existingId INT(10) DEFAULT NULL; 

    SELECT 
     MAX(id) 
    INTO 
     existingId 
    FROM 
     booking 
    WHERE 
     booking.dirty_id IS NULL AND 
     booking.lang = NEW.lang AND 
     booking.created >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) AND 
     (LEVENSHTEIN(booking.name, NEW.name)/LENGTH(booking.name)) < 0.3; 

    SET NEW.dirty_id = existingId; 
END// 
DELIMITER ; 

您可以阅读更多关于莱文斯坦:

现在您可以使用Duplicate_for检测重复项。

+0

谢谢你的建议,我已经成立了Levenshtien,但我在触发器方面遇到了一些问题。如何在触发器中声明现有ID? –

+0

添加了触发器的代码。预订是餐桌的名字。 –

+0

谢谢@ niko-hujanen,由于某种原因,Levenshtien似乎并没有工作。我仍然在玩它。我已经验证存储过程的作品,但我似乎得到一个重复的标志,不管新名称是什么。 –

0

这是一个很好的问题..让我在夜间清醒很久..:D:D 首先,你不需要任何触发器和/或额外的行来解决这个问题。

这是我迄今为止尝试过的。

SELECT 
t3.* 
FROM 
Table1 t1 
INNER JOIN 
Table1 t2 
ON 
(
    t2.Rec_id > t1.Rec_id 
    AND t2.Language = t1.Language 
    AND ABS(TIMESTAMPDIFF(MINUTE, t1.Date_time, t2.Date_time)) <= 15 
    #AND (
    # SOUNDEX(t1.App_name) LIKE CONCAT(TRIM(TRAILING '0' FROM SOUNDEX(t2.App_name)), '%') 
    # OR 
    # SOUNDEX(t2.App_name) LIKE CONCAT(TRIM(TRAILING '0' FROM SOUNDEX(t1.App_name)), '%') 
    #) 
) 
INNER JOIN 
Table1 t3 
ON(t1.Rec_id = t3.Rec_id OR t2.Rec_id = t3.Rec_id) 
GROUP BY t3.Rec_id 

我已经注释掉SOUNDEX一部分。这70%的匹配是模糊的东西,是不是.. 尝试取消对查询的SOUNDEX部分检查它是否解决了更大的问题。

相关问题