2013-06-20 52 views
0

我正在构建一个帖子可以有多个标签的典型帖子和标签应用程序。我坚持设置数据库模式。我至今:具有多个标签的帖子的数据库模式

帖子:
POST_ID PRIMARY KEY
POST_TITLE
POST_BODY
POST_DATE
POST_USERID

标签:
TAG_ID PRIMARY KEY
TAG_TAGNAME


PT:
PT_ID
PT_POSTID
PT_TAGID


当用户提交一则讯息,我插入表单数据进入后表。下一步我循环浏览用户提供的标记名,看看它们是否在TAG_TAGNAME字段中。如果有匹配,请抓住ID并将其插入PT表格中。 ELSE将名称插入到标记表中,并获取该标识并将其插入到PT表中。两者都与POST表插入中生成的postid一起使用。
最后,我有一个名为PTVIEW视图与下面的模式:

SELECT *
FROM dbo.PT
JOIN后
ON PT_PostID = dbo.Post.POST_ID
JOIN标签
ON PT_TagID = tag.TAG_ID

下面是select * from PTVIEW的示例结果
enter image description here


问题是我无法获得独特帖子及其标签的视图。
我正在使用MSSQL,所以我没有内置到mySQL中的Group_concat函数。

我无法构建初始页面,该页面将显示每个帖子及其相关标签,如在主页上使用的stackoverflow。我在PTVIEW中做了什么错误?

回答

2

你基本上有两个选择:

  1. 其分解成2个不同的查询,得到一个讯息,然后得到它的 相关标签。
  2. 使用如下语句 这种拼接标记为单场:
SELECT DISTINCT 
     P.Post_ID , 
     SUBSTRING((SELECT ',' + T.TAG_TAGNAME AS [text()] 
        FROM dbo.PT PT 
          INNER JOIN dbo.Tag T ON PT.PT_TAGID = T.TAG_ID 
        WHERE P.POST_ID = PT.POST_ID 
        FOR 
        XML PATH('') 
       ), 2, 1000) [Tags] 
FROM dbo.Post P 

即使第二个选项看起来有点俏皮,第一个选项有我个人的喜好。 我认为第二个不太可读,在较大的数据集上性能不会很好。

+0

如果我用的是第一选择,我能想到的列出职位及标签的顶部#的唯一方法是使用一个嵌套循环。抓取每个postID,然后选择另一个来获取标记名。我错了吗?我觉得如果有很多帖子,这也会成为服务器上的负载。 – jwimmer

1

这是我学会如何做到的。

SELECT * 
    ,(
     SELECT TAG_TAGNAME+ ', ' 
     from PT 
     JOIN Tag ON PT_TagID = TAG_ID 
     Where PT_PostID = POST_ID 
     ORDER BY TAG_TAGNAME 
     FOR XML PATH('') 
    ) AS Tags 
    FROM Post 
相关问题