如何从一个表中选择一个字段,该表是另一个表的一个字段中包含的字符串的一部分?

时间:2011-07-05 02:46:43

标签: php mysql sql

使用PHP和MYsql。我有2个表,如

  • table'tag':字段'id'和'tag'('tag'是varchar)

  • 表'entry':有字段'tags'和其他字段('tags'是varchar,它存储许多单词作为标记,每个单词用逗号分隔。然后我用函数'explode'从中提取标签要存储在数组'$ tags'中的字符串。表'entry'中的所有标记都存储在表'tag'中。)

我想要的是从表'tag'中选择所有'标签',它们是具有给定标签(变量$ tag)的表'entry'的相同字符串'标签'中的标签。但不知道,我只是尝试从表'entry'中选择SELECT标签'tags'中的哪个字符串包含指定的标签(变量$ tag)。我的当前代码是

$count=0;
$sql="SELECT tags FROM entry WHERE tag LIKE '%$tag%'";
$result = mysql_query($sql);
while($data=mysql_fetch_array($result)){
  if(mysql_num_rows($result)!=0){
    $tags1=explode(',',$data['tags']);
    for($loop=0; $loop<=count($tags1)-1; $loop++){
      if(!in_array($tags1[$loop], $tags2)){
        $count+=1; 
        $tags2[$count]=$tags1[$loop];
      }
    }
  }
}

2 个答案:

答案 0 :(得分:2)

超低效,SQL注入攻击倾向于将其作为一个语句执行的方式是:

$sql="SELECT tags FROM entry WHERE 1=1 ";

然后在运行之前将每个标记添加到查询中:

$sql.="AND tag LIKE '" . $tags1[$loop] . "' ";

如果您想匹配任何代码而不是所有代码,请将AND替换为OR

我真的建议对标记进行规范化,并考虑不以这种方式构建SQL查询。

答案 1 :(得分:2)

您解决此问题的困难都源于您将标签列表存储在一个列中。

您确实需要添加一个交集表,以包含标记和条目之间many-to-many relationship的数据。这是设计关系数据库的正确方法,如果您这样做,许多SQL查询将变得更有效。

例如,要获取与标记$tag匹配的条目中的所有标记:

<?php

$sql = "SELECT t1.tag FROM tag AS t1
INNER JOIN entries_tags AS e1 ON e1.tag = t1.id
INNER JOIN entries_tags AS e2 ON e2.entry = e1.entry
INNER JOIN tag AS t2 ON t2.id = e2.tag
WHERE t2.tag = ?";

$stmt = $pdo->prepare($sql);
$result = $stmt->execute( array($tag) );

$data = $result->fetchAll();
$count = count($data);

我在我的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming中写了一章来详细说明这个设计引起的实际问题。