我试图做一个基于标签的CMS/博客。没什么复杂的,因为这主要是一个学习练习。我使用的是PHP和MySQL,不过我怀疑如果将自定义的DB代码写到磁盘上,这会更容易。
不管怎样,我想有两个表,一个标签列表,一个名字和id,一个帖子列表,一个内容,一个标签的id列表。但是,似乎不能将整数数组放在表的单个字段中。所以我制作了第三个表posttags,它包含OwningPost和TagID。表中有多个重复的OwningPost,每个都有不同的标记id,因此一个post可以有多个标记。这看起来不太干净,但我想不出比这更好的了。
现在,我想得到一个列表,列出所有有特定标签,但没有其他特定标签的帖子。我甚至还没有找到not标签,我仍然被贴在包含指定标签的帖子上。我有这个密码:

printPostsTagged(array('Blog Post'),array('First'));
function printPostsTagged($iTags,$eTags)
{
 $tagQ="SELECT ID from tags WHERE (";
 for($i=0;$i<count($iTags)-1;$i++)
    $tagQ=$tagQ."Name='".$iTags[$i]."' OR ";
 $tagQ=$tagQ."Name='$iTags[$i]')";
 $tagR=mysql_query($tagQ);
     ...

它通过将所有ITAG(包括的标记)与ORs串接在一起进行查询,这将得到ITAG中每个标记的ID列表,现在我想使用整个列表从posttags中选择OwningPost,然后使用该索引列表从posttags表中获取所有对应的Post列表。
我以前没有使用过SQL,但是我的google搜索似乎没有任何结果,我强烈地感觉我在这里做了完全错误的事情

最佳答案

要获得良好的表模式,请查看:http://forge.mysql.com/wiki/TagSchema#Recommended_Architecture
通常项目不是按标记“name”查询的,而是按标记id或标记slug查询的,总之,您可以使用JOIN简化您的函数:

function printPostsTagged($iTags, $eTags) {
  $in = '"' . implode('", "', array_map('mysql_real_escape_string', $iTags)) . '"';
  $sql = "SELECT p.* FROM posts p
   INNER JOIN post_tag pt ON pt.post_id = p.post_id
   INNER JOIN tags t ON pt.tag_id = t.tag_id
  WHERE name IN ($in)";

  // it removes duplicates and fetch just the posts with all the iTtags assigned
  $sql .= " GROUP BY p.id HAVING COUNT(p.id) = " . count($iTags);

}

07-24 09:49
查看更多