2016-08-21 41 views
1

我想从一个大的语料库(100万+记录)的字符串运行统计测试,我不知道如何最好在mySQL中直接执行此操作,而不是在php中解析它,采取(至少根据我的技能)年龄。在mySQL中结合字符串

表:

ID    Words 
----------  ------------- 
1    ham 
2    cheese 
3    lettuce 
4    tomato 
5    onion 

所需的输出,我想实现是创建一个包含双字母组和每个字符串的八卦如下两个新列:

ID    Words   Bigrams   Trigrams 
----------  ------------- -------------  ------------- 
1    ham    ham_cheese  ham_cheese_lettuce 
2    cheese   cheese_lettuce cheese_lettuce_tomato 
3    lettuce   lettuce_tomato lettuce_tomato_onion 
4    tomato   tomato_onion  ........ 
5    onion   .........   ........ 

我想知道是否有是在mySQL中做到这一点的一种方式?

+1

如果这些总是由ID&ID + 1&ID + 2的逻辑,或者是你寻找*所有排列*? – Kaii

+0

@Kaii它会永远是ID,+1,+ 2 – Jacob

+2

已经尝试加入?我们可以帮助你改善你的查询...如果你尝试.. – scaisEdge

回答

1

做到这一点的最佳方式,将与自我加入。如果表的名称将是all_words与领域ID

SELECT 
    first.id, 
    first.word, 
    CONCAT(first.word, '_', second.word) AS bigram, 
    CONCAT(first.word, '_', second.word, '_', third.word) AS trigram 
FROM 
    all_words first 
LEFT JOIN 
    all_words second ON first.id + 1 = second.id 
LEFT JOIN 
    all_words third ON first.id + 2 = third.id 

随着CONCAT()函数您连接从不同表中的字为一列。如果你想要的二元和三元栏是空的最后行(而不是只有第一个字),使用

IF(second.word IS NOT NULL, CONCAT(first.word, '_', second.word), '') AS bigram 

的二元和一些相等卦。

+1

注意:此解决方案依赖随后递增的ID,没有任何间隙。 – Kaii

+0

谢谢你的回答。我希望能尽快给您提供反馈,但查询仍在运行,看起来需要一段时间。再次感谢,我会让你知道它是否工作;) – Jacob

+1

@Jacob为了测试它是否有效,你应该在查询中添加“LIMIT 100”。您当前的查询为所有行执行此计算 - 当然,需要一段时间才能向您的客户端传递数百万行。 – Kaii

1

操纵PHP中的数组应该比在MySQL做快得多,但是从数据库中获取你的结果,你必须使用一个join

select t1.id, t1.words, 
     concat(t1.words, '_', t2.words) as Bigrams 
     concat(t1.words, '_', t2.words, '_', t3.words) as Trigrams 
from tablename t1 
left join tablename t2 
on t2.id = t1.id + 1 
left join tablename t2 
on t3.id = t1.id + 2 
+0

注意:此解决方案依赖随后递增的ID,没有任何间隙。 – Kaii

+0

感谢您的回答,我正在测试建议的加入,但查询需要一段时间 – Jacob

+1

@Jacob是的,这将需要一段时间。正如我所说的,在PHP中进行数组操作更快,mysql现在必须执行连接,并且需要时间从数据库中检索3倍的数据量。 (而且我假设你有'id'作为主键,否则这真的很慢)。 – Solarflare

1

雅可以在同一个表进行多次join并保持如果ID+1

select mytable.id, mytable.value        Words 
    , concat(mytable.value,'_',bigram.value)     bigrams 
    , concat(mytable.value,'_',bigram.value,'_',trigram.value) trigrams 
from mytable 
left join mytable bigram on (mytable.id + 1 = bigram.id) 
left join mytable trigram on (mytable.id + 2 = trigram.id) 
+0

感谢您的答案,我正在测试建议的连接,但查询需要一段时间 – Jacob