PostgreSQL-从文本数组获取所有子组

时间:2018-08-01 05:52:55

标签: sql postgresql

我有一个带有职位名称的表 例如

  • 周末需要咖啡师
  • 需要一个咖啡师,每小时24美元
  • 周末需要保姆,每小时24美元

我正在尝试获取一些独特的短语 例如  -2 x需要  -2 x需要咖啡师  -周末2次  -2 x  -每小时2 x 24 $

我已经运行了一个表格,将我的文本转换成单词数组

CREATE TABLE IF NOT EXISTS job_words (
    source VARCHAR, 
    title VARCHAR,
    words VARCHAR[]
)

我已经分割标题并作为单词插入到该表中

insert into job_words
select 'job-title', raw_title, string_to_array(raw_title, ' ') from jobs 

最长的句子中有49个单词 我想找到2到10个字长的词组 如果可能的话,很乐意使用另一张表写入或直接查询

样品查询以获取一些样品数据

select cardinality(words) no_of_words, words, title from job_words 
where cardinality(words) > 4 and cardinality(words) < 10 and title ilike 'need a%'
order by title limit 100

样本数据

8;"{Need,a,baby,sitter,for,an,amazing,girl}"
7;"{Need,a,baby,sitter,for,casual,sitting}"
8;"{Need,a,babysitter,for,our,19,months,old}"
9;"{Need,a,babysitter,for,our,4,year,old,son}"
9;"{Need,a,babysitter,for,our,little,reyon,19,months}"
7;"{Need,a,babysitter,-,look,no,further}"
5;"{Need,a,babysitter,or,tutor?}"
9;"{Need,a,baby,sitter,tonight,kids,are,already,sleeping}"
6;"{Need,a,Baker,now?,I'm,available!}"
6;"{Need,a,barista,all,rounder,ASAP}"
8;"{NEED,A,BARISTA???,full,time,or,part,time.}"
5;"{Need,a,brick,labourer,urgently}"
9;"{Need,a,care,giver,for,a,Month,old,baby}"
7;"{Need,a,Carer,-,After,School,hours}"
7;"{Need,a,Carpenter,-,build,a,cubby}"
5;"{Need,a,Carwash,staff,asap}"
5;"{Need,a,catering,assistant,job}"
9;"{Need,a,change,from,customer,service?,Look,no,further!}"
5;"{Need,a,change,of,scenery?}"
6;"{NEED,A,CLEANER,-,asap,start}"
6;"{Need,a,cleaner,for,daily,work}"
6;"{Need,a,cleaner,for,daily,work}"
9;"{Need,a,Cleaner,for,hotel,in,Belmont,near,Geelong}"
9;"{Need,a,Cleaner,for,hotel,in,Fyansford,near,Geelong}"
9;"{Need,a,Cleaner,for,hotel,in,Queenscliff,near,Geelong}"
5;"{Need,a,cleaner,for,mcdownal}"
7;"{Need,a,cleaner,for,tomorrow,pay,cash}"
7;"{Need,a,cleaner,for,tomorrow,pay,cash}"
5;"{Need,a,cleaner,in,Brisbane}"
6;"{Need,a,cleaner,in,Roxburghpark,Area}"
7;"{Need,a,cleaner,on,a,weekly,basis}"
7;"{Need,a,cleaner,on,Sunday,18th,June}"
9;"{Need,a,cleaning,team,for,your,building,or,office?}"
8;"{Need,a,concreter,to,start,full,time,/paving}"
6;"{Need,a,contract,climber,on,Tuesday}"
7;"{Need,a,cook,for,Road,Trip,Film}"
6;"{Need,a,delivery,driver,in,kew}"
8;"{Need,a,dishwasher,-,Wetherill,Park,6,days}"
7;"{Need,admin,done,for,hair,salon,asap}"
7;"{Need,admin,done,for,hair,salon,asap}"
7;"{Need,admin,done,for,hair,salon,asap}"
6;"{Need,a,driver,at,8:00,tonight}"
8;"{Need,a,driver,for,my,4.5,tomne,truck}"
7;"{Need,a,driver,in,a,Korean,restaurant}"
6;"{NEED,A,EXPERIENCED,CAR,WASH,STUFF}"
8;"{Need,a,flexible,babysitter,to,suit,shift,work}"
7;"{Need,a,fridge,picked,up,tommorow,Saturday}"
7;"{Need,after,school,care,with,pick,up}"
5;"{need,a,fulltime,female,cleaner}"
5;"{Need,a,full,time,job}"
8;"{Need,a,full,time,nanny,at,Baulkham,Hills}"
6;"{Need,a,"fun,","reliable,",interactive,babysitter}"
9;"{Need,a,gardener,/,labourer,tomorrow,for,5,hours}"
6;"{Need,a,gardener,or,labourer,tomorrow}"
6;"{Need,a,girl,for,sharing,room}"
8;"{Need,a,girl,or,boy,for,cleaning,job}"
6;"{Need,a,good,Barista,in,putney}"
8;"{Need,a,good,painter,for,the,next,month}"
7;"{Need,a,gyprock,setter,for,monday,23/01/17}"
9;"{Need,a,handy,person,in,our,new,work,shop}"
8;"{Need,a,helper,for,a,house,removals,truck}"
5;"{Need,a,house,Cleaner,?}"
6;"{Need,a,house,cleaner?,Call,now}"
6;"{Need,a,house,cleaner?,CALL,NOW!}"
8;"{Need,a,house,cleaner,for,this,afternoon,$30p/h}"
5;"{Need,a,housekeeper,tomorrow,morning}"
9;"{Need,a,HR,driver,for,one,day,a,week}"
8;"{need,a,invester,for,the,new,restaurant,Urgently}"
7;"{Need,a,job,asap,will,start,tomorrow}"
9;"{Need,a,job,?,Backpackers,wanted,+,FREE,ACCOMODATION}"
5;"{Need,a,job,for,weekend.}"
8;"{need,a,job,in,day,time,and,weekends}"
7;"{Need,a,job,of,cleaning,or,handkitchen}"
5;"{NEED,A,JOB?!,Start,immediately!!}"
5;"{need,a,job,(student,here)}"
6;"{Need,a,job,to,start,asap}"
9;"{Need,a,kitchen,hand,for,Indian,take,away,shop}"
8;"{Need,a,labourer.,Easy,work.,Monday,or,Tues}"
6;"{need,a,labourer,for,7,weeks}"
5;"{Need,a,labourer,for,today}"
5;"{Need,a,labourer,next,week}"
9;"{Need,a,last,minute,barista,or,chef?!,Staff,cancelled?!}"
9;"{Need,a,live,in,nanny,for,our,2,sons}"
8;"{Need,a,local,Electrician?,Look,no,further,:)}"
8;"{Need,a,male,cleaner,for,a,busy,restaurant}"
6;"{Need,a,man,and,a,ute!!!}"
9;"{NEED,A,MAN,AND,UTE,MONDAY,26th,AFTER,5PM}"
9;"{NEED,A,MANSPOWER,TO,HELP,US,IN,OUR,MOVING}"
8;"{Need,an,after-school,nanny,for,month,of,October}"
5;"{Need,a,Nanny,/,Babysitter}"
6;"{Need,a,nanny,for,2,kids}"
9;"{Need,a,nanny,for,3,days,after,school,care}"
7;"{Need,a,Nanny,for,7,year,old}"
9;"{Need,a,nanny,for,a,few,days,a,week}"
9;"{Need,a,nanny,for,after,school,pick,and,care}"
8;"{Need,a,nanny,for,immediate,start,on,Thursdays}"
9;"{Need,a,nanny,for,my,3,year,old,daughter}"
9;"{Need,a,nanny,for,my,3,year,old,daughter}"
6;"{Need,a,nanny,for,one,day.}"
7;"{Need,a,nanny,for,"Rydges,",Campbelltown,5.45-10.30pm}"

1 个答案:

答案 0 :(得分:1)

我明白了。这是您期望的结果吗?

snprintf

如果这是您的预期结果,请查询它。但是我不确定您是否应该使用庞大的数据集来执行此操作!

我从简单的短语开始,而不是从数组的示例数据开始。另外,我为每个短语添加了一个id列:

phrase_part                                                                count  
-------------------------------------------------------------------------  -----  
{"Need","a"}                                                               32     
{"Need","a","cleaner"}                                                     9      
{"a","cleaner"}                                                            9      
{"cleaner","for"}                                                          5      
{"Need","a","babysitter"}                                                  5      
{"a","babysitter"}                                                         5      
{"a","cleaner","for"}                                                      5      
{"Need","a","cleaner","for"}                                               5      
{"for","hotel","in"}                                                       3      
{"near","Geelong"}                                                         3      
{"hotel","in"}                                                             3      
{"Cleaner","for","hotel"}                                                  3      
{"for","hotel"}                                                            3      
{"babysitter","for","our"}                                                 3      
{"for","our"}                                                              3      
{"babysitter","for"}                                                       3      
{"a","Cleaner","for"}                                                      3      
{"Need","a","babysitter","for"}                                            3
...
{"NEED","A"}                                                               2      
{"a","cleaner","for","daily"}                                              2      
{"Need","a","change"}                                                      2      
{"daily","work"}                                                           2      
{"pay","cash"}                                                             2      
{"a","cleaner","in"}                                                       2      
{"Need","a","cleaner","for","tomorrow","pay","cash"}                       2      
{"for","casual","sitting"}                                                 1      
{"concreter","to","start","full"}                                          1      
{"a","change","from","customer","service?","Look"}                         1      
{"a","contract","climber"}                                                 1      
{"Roxburghpark","Area"}                                                    1      
{"Need","a","Carwash"}                                                     1
...

A:将普通短语格式化为单个单词数组,并将表格扩展为每行一个单词

B:添加一个单词计数器以使用窗口函数来识别短语的第n个单词

C:将短语与自己交叉连接;更好的说:将同一个词的每个后续词连在一起

D:此窗口功能汇总短语词。它会产生类似

的结果
WITH phrases as (
    SELECT 
        *, 
        row_number() over (partition by id) nth_word     -- B
    FROM (
        SELECT 
            id, 
            unnest(string_to_array(phrase, ' ')) as word -- A
        FROM testdata.phrases
    )s
)
SELECT 
    phrase_part, 
    count(phrase_part) FILTER (WHERE cardinality(phrase_part) >= 2) -- E
FROM (
    SELECT 
        *, 
       array_agg(b.word) over (partition by a.id, a.nth_word order by a.id, a.nth_word, b.nth_word) --D
            as phrase_part 
    FROM phrases a 
    JOIN phrases b                                       -- C
    ON (a.id = b.id AND a.nth_word <= b.nth_word)
) s
GROUP BY phrase_part
ORDER BY COUNT DESC

E:按短语分组并计数元素。使用filter子句可以计算不同的基数。