2012-05-01 22 views
0

我有這個表:SQL井號標籤的正則表達式表

p_id  name  skills 
1   Sam  #IT #communication #administration 
2   Alex  #French #Trainer 

我想要一個SQL查詢來輸出這個

ID  p_fid skill 
    1  1  IT 
    2  1  communication 
    3  1  administration 
    4  2  French 
    5  2  Trainer 

使用PostgreSQL

非常感謝

+0

的問題是,我甚至不知道從哪裏開始,我知道肯定是我需要正則表達式,但問題是在SQL你不能使用循環,你可以看到一行可能有多個井號標籤,所以基本上我卡住了 – Ali

回答

1

事情是這樣的:

CREATE TABLE testbed (p_id int4,name varchar(50),skills text); 
INSERT INTO testbed VALUES 
    (1,'Sam','#IT #communication #administration'), 
    (2,'Alex','#French #Trainer'); 

SELECT row_number() OVER() AS id, 
     p_fid, skill 
    FROM (SELECT 
     p_id AS p_fid, 
     regexp_split_to_table(
      regexp_replace(skills, '^#', ''), 
      '[ ]+#') AS skill FROM testbed) AS s; 

請看看文檔WindowString manipulationArray功能。

如果你真的需要在你的技能位置,需要一點更復雜的查詢控制:

WITH arrays AS (
    SELECT p_id, 
      regexp_split_to_array(regexp_replace(skills, '^#', ''), '[ ]+#') arr 
     FROM testbed 
), series AS (
    SELECT p_id, generate_series(1, array_upper(arr, 1)) i 
     FROM arrays 
) 
SELECT row_number() OVER (ORDER BY a.p_id, s.i) AS id, 
     a.p_id AS p_fid, 
     a.arr[s.i] AS skill 
    FROM arrays a 
    JOIN series s ON a.p_id = s.p_id 
ORDER BY a.p_id, s.i; 
+0

工作就像一個魅力,謝謝:) – Ali

+0

抱歉,但你是什麼意思「控制你的技能的位置」? @vyegorov – Ali

+1

@Ali,第二個查詢將'skills'分成數組,然後使用'p_id' +數組索引通過'ORDER BY'顯式地排序結果。第一個查詢意味着沒有排序,這使得「ID」列的含義不清楚。 – vyegorov

1

如果您關於使用MS SQL Server作爲RDBMS,以及skills列除hashtags和si之外不包含其他內容空格,您可以將skills列轉換爲XML字符串,然後使用SQL Server的內置XML操作函數將此字符串拆分爲單獨的行。

以下是適用於您在問題中指定的數據示例的方法。

create table people_skills 
(
    p_id int identity(1, 1) primary key clustered, 
    name nvarchar(200), 
    skills nvarchar(1000) 
) 

go 

insert into people_skills (name, skills) values ('Sam', '#IT #communication #administration') 
insert into people_skills (name, skills) values ('Alex', '#French #Trainer') 

go 

select 
    row_number() over (order by ps.p_id) as ID, 
    ps.p_id as p_fid, 
    cast(x.skill_node.query('text()') as nvarchar(100)) as skill 
from 
    (
     select 
      *, 
      -- Assuming that there are no leading and trailing spaces and that all hashtags are separated by single space. 
      (cast('<skills>' + (replace(replace(skills, '#', '<skill>'), ' ', '</skill>')) + '</skill></skills>' as xml)) skills_xml 
     from 
      people_skills 
    ) ps 
cross apply 
    ps.skills_xml.nodes('/skills/skill') as x(skill_node) 

如果skills列可以包含不同的主題標籤和空格等信息,那麼你可能需要轉變到skills XML比我上面使用的一個「聰明」的算法。

+0

看到我的編輯,對不起我的壞,很好的信息:) – Ali