0

私はこのテーブルを持っています:

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 の使用

どうもありがとう

4

2 に答える 2

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;

Window文字列操作、および配列関数のドキュメントをご覧ください。

スキルの位置を本当に制御する必要がある場合は、もう少し複雑なクエリが必要です。

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;
于 2012-05-03T11:54:54.467 に答える
1

MS SQL Server を RDBMS として使用することに問題がなく、かつskills列にハッシュタグと単一スペース以外のものが含まれていない場合は、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 に変換するために、上記で使用したアルゴリズムよりも「スマートな」アルゴリズムが必要になる場合があります。

于 2012-05-01T17:34:29.047 に答える