$ query返回结果但不是我想要的 - 有计数?

时间:2011-01-15 14:56:40

标签: mysql sql

我会重新开始,

让我们说我的数据是:

表格元素(id,name,....)


1,名称元素1,....

2,名称元素2,....

3,名称元素3,....

表格标签(id,name,id_element,....)


1,快乐,1

2,结果,1

3,非常,1

4,元素,2

5,另一个,3

6,元素,1

7,快乐,2

因此,如果搜索“非常,快乐,元素,结果”:我想要的结果


1)id = 2的元素,因为它有所有标签

2)id = 1的元素,因为它有标签'element'和标签'happy'(只有2个标签)

3)....(仅少3个标签)

因此,如果搜索“ happy,元素”:我想要的结果


1)id = 1的元素,因为它包含所有标签(不再有)

2)id = 2的元素,因为它有标签'element'和标签'happy'(还有两个标签)

3)....还有3个标签


这是对我的查询的回应: (它不符合我写的要求,但它是第一个用匹配标签找到的测试)

SELECT element.id as id_deseada,tagg.* FROM element,tagg WHERE tagg.id_element = element.id AND tagg.nombre IN ('happy','tagg','result') GROUP BY tagg.id_element ORDER BY element.votos 

这会返回10个重复的元素......:S并且甚至没有所有标记(并且在数据库中有标记有'happy'结果)


如果它有帮助,那就是我如何得到标签的元素(按名称和只有一个标签)

$query = "SELECT element.id FROM element,tagg WHERE tagg.nombre = '$nombre_tagg' AND tagg.id_element = element.id  AND lan = '$lan' GROUP BY tagg.id_element";

我希望现在更容易理解,原谅我的英语.. :)

-------编辑----------

我的查询有效,来自:http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html(第二个例子是我的结构)

    SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3

想象书签是元素,类别是标签(对于我的例子)

它工作得很好,它返回带有ALL标签的所有元素,但它返回带有额外标签的文章,

该查询的

可能是:

带有标签的元素6(书签,webserbice,semweb,extratag)

我希望这个额外的标签(实际上是任何其他额外的标签)与HAVING COUNT有关吗?

我知道

非常感谢您可能的出售!

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你就有多对多的关系,你想在同一个领域同时满足多个条件。

为此,您需要使用MySQL的HAVING子句。由于我不知道你的数据库结构,我将为这个例子做一个。

<强>对象

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| object_id  | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | NO   |     | NULL    |                |
| otherfield | text         | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

<强>代码

+--------+--------------+------+-----+---------+----------------+
| Field  | Type         | Null | Key | Default | Extra          |
+--------+--------------+------+-----+---------+----------------+
| tag_id | int(11)      | NO   | PRI | NULL    | auto_increment |
| name   | varchar(255) | NO   |     | NULL    |                |
+--------+--------------+------+-----+---------+----------------+

<强> object_tag

+-----------+---------+------+-----+---------+-------+
| Field     | Type    | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| object_id | int(11) | NO   |     | NULL    |       |
| tag_id    | int(11) | NO   |     | NULL    |       |
+-----------+---------+------+-----+---------+-------+

现在,要检索包含其所有标记的对象,您可以执行以下操作:

SELECT object.*,tag.name as tag FROM object 
  LEFT JOIN object_tag ON object_tag.object_id = object.object_id 
  LEFT JOIN tag ON object_tag.tag_id = tag.tag_id

这给你一些类似的东西:

+-----------+-----------+------------+------+
| object_id | title     | otherfield | tag  |
+-----------+-----------+------------+------+
|         1 | My object | something  | foo  |
|         1 | My object | something  | bar  |
|         1 | My object | something  | baz  |
+-----------+-----------+------------+------+

现在,由于您无法进行WHERE tag='foo' AND tag='bar',因为无法匹配,您必须使用HAVING子句。

SELECT object.* FROM object 
  LEFT JOIN object_tag ON object_tag.object_id = object.object_id 
  LEFT JOIN tag ON object_tag.tag_id = tag.tag_id
  WHERE tag.name IN ('foo', 'bar')
  GROUP BY object.object_id
  HAVING COUNT(1) >= 2;

现在这会给你:

+-----------+-----------+------------+
| object_id | title     | otherfield |
+-----------+-----------+------------+
|         1 | My object | something  |
+-----------+-----------+------------+

HAVING子句告诉MySQL只有2个或更多标签(COUNT(1) >= 2)与结果集匹配才能返回。