将列拆分为逗号&插入(多对多)表

时间:2016-01-19 06:56:52

标签: sql postgresql

我有一张标签表:

id  | text
----------
 1  | art
 2  | sports
 3  | history
 4  | science

和一个帖子表(临时):

id  | post             | tags
-----------------------------
 1  | 'random post 1'  | 'art, 'history'
 2  | 'random post 2'  | 'science'
 3  | 'random post 3'  | 'art, science, history'
 4  | 'random post 4'  | 'sports, science'

我想建立这些标签和帖子之间的多对多关系,我正在试图找出构建下表(posts_tags)所需的sql查询

id  | post_id | tag_id
-----------------------------
 1  | 1       | 1
 2  | 1       | 3
 3  | 2       | 4
 4  | 3       | 1
 ...

从文档中,我可以看到我们可以拆分posts.tags

regexp_split_to_table(posts.tags, E',') AS tags

但不确定如何使用所需的SQL命令使其工作。

2 个答案:

答案 0 :(得分:1)

首先,您需要创建表格posts_tags

CREATE TABLE posts_tags (
  id      serial  PRIMARY KEY,
  post_id integer REFERENCES posts,
  tag_id  integer REFERENCES tags
);

INSERT INTO posts_tags (post_id, tag_id)
  SELECT p.id, t.id
  FROM posts p, regexp_split_to_table(p.tags, ',') AS x(tag), tags t
  WHERE btrim(x.tag) = t."text";

regexp_split_to_table()上的posts function uses a lateral join(第7.2.1.4和.5节),以便它可以访问字段tags。实际上,这可以作为JOIN使用:id的每个组合与同一行中的标记相同。然后,您可以将代码与text表格中的tags字段进行匹配,以便SELECT id代码。

答案 1 :(得分:0)

您可以先创建posts_tags表并根据这两个表填充它:

CREATE TABLE posts_tags(ID SERIAL PRIMARY KEY,
                        post_id INT NOT NULL,  -- define foreign keys
                        tag_id INT NOT NULL);

INSERT INTO posts_tags(post_id, tag_id)
SELECT c.id, t.id 
FROM (SELECT *, TRIM(regexp_split_to_table(p.tags, E',')) AS tag
      FROM posts p) AS c
JOIN tags t
  ON t."text" = c.tag

SELECT *
FROM posts_tags;

SqlFiddleDemo

输出:

╔═════╦══════════╦════════╗
║ id  ║ post_id  ║ tag_id ║
╠═════╬══════════╬════════╣
║  1  ║       1  ║      1 ║
║  2  ║       1  ║      3 ║
║  3  ║       2  ║      4 ║
║  4  ║       3  ║      1 ║
║  5  ║       3  ║      4 ║
║  6  ║       3  ║      3 ║
║  7  ║       4  ║      2 ║
║  8  ║       4  ║      4 ║
╚═════╩══════════╩════════╝