2014-04-09 51 views
0

我写了一个SQL查询来获取单词的频率。我创建了一个新列,用#分隔单词,然后计算它们的出现次数。但是,查询需要花费数小时才能在完整数据集上运行(大约14,000行)。所以我只用了几个ID就可以了,而且我得到的单词数量应该是16,000+,而只有20左右。SQL计数查询返回不正确的数字

这里是我的查询:

WITH mydata as 
( 
--query for test column 
SELECT REGEXP_REPLACE(UPPER(TEST), ' ', '#') test 
    FROM (SELECT REGEXP_REPLACE (replace(description,'-','.'), '[' || 
    REGEXP_REPLACE (replace(description,'-','.') || '!', '[^[:punct:]]') || ']') test 
    FROM my_table) 
), 
splitted_words as 
( 
SELECT REGEXP_SUBSTR(TEST,'[^#]+', 1, level) AS word 
FROM mydata 
CONNECT BY level <= LENGTH(regexp_replace(TEST,'[^#]')) + 1 
AND PRIOR TEST = TEST 
AND PRIOR sys_guid() IS NOT NULL 
) 
SELECT word, 
COUNT(1) 
FROM splitted_words 
GROUP BY word; 

我的专栏,我遍历看起来是这样的:

TEST 
--------------------------------------------- 
SPOKE#WITH#MR#SMITHS#ASSISTANT 
EMAILED#FOR#VISIT 
SCHEDULING#OFFICE#LM#FOR#VISIT 
LM#FOR#VISIT 
LM#FOR#VISIT 
PHONE#CALL 
--------------------------------------------- 

,但我的结果看起来像这样:

word | count 
-----|------ 
LM | 20 
Visit| 24 
Phone| 8161 
With | 16 
Email| 16080 

明确时,“电子邮件”一词不会出现16,000次出现

任何想法为什么我得到一些字疯狂高数字? )并因此导致查询花费12+小时以上运行?)

回答

2

发生这种情况是因为您检查了AND PRIOR TEST = TEST

在你的榜样,这将发现两行,不仅是一个你当前正在处理:

LM#FOR#VISIT 
LM#FOR#VISIT 

,如果你有一些ID列使用它的工作,或者你甚至可以检查改为PRIOR ROWID = ROWID

+0

哦,这很有道理!我将如何获得我的测试列中的row_id?所以我可以检查之前的row_id?我相对较新的SQL,它需要几个小时才能得到这个查询半正确 – Ted

+0

'ROWID'是Oracle已经提供的一列,所以你可以像我描述的那样使用它。如果桌子上有主键,请改用它。 –