2012-02-15 61 views
1

所有元素我有这个数组:MySQL的选择阵列

$results = array('1', '3', '123') 

与此表:

id | item | tag 
1  1  1 
2  1  3 
3  1  123 
4  2  1 
5  3  1 
6  4  3 

我要执行这样的查询:

SELECT item FROM table WHERE ALL 3 TAGS OF THE ARRAY EXIST. 

在示例我只想返回Item = 1,因为它是唯一一个包含数组全部3个标签的Item。

到目前为止,我有这样的:

$query .= " SELECT item FROM #__table WHERE tag IN ('"; 
$query .= implode("','",$results); 
$query .= "')"; 

但它不返回正确的项目,而是返回已至少与阵列中的一个元素相关的所有项目。

+0

什么回报?你有错误吗?或者“只是”一个空的结果? – 2012-02-15 21:39:57

+0

你真的希望他们仅仅依靠他们存在,还是应该你的数组在逻辑上与每个表格列相关? (item,id,tag) – hexparrot 2012-02-15 21:41:06

+0

@Cassy它只返回至少有一个元素的数组。 – 2012-02-15 21:42:10

回答

4

要使IN作为AND工作而不是OR,请使用HAVING子句以确保获得与IN子句中存在的相同数量的不同返回值。

SELECT item 
    FROM YourTable 
    WHERE tag IN ('1', '3', '123') 
    GROUP BY item 
    HAVING COUNT(DISTINCT tag) = 3 
+0

如果数组中元素的数量是动态的并且不总是3,该怎么办?它应该具有计数(DISTINCT标记)=计数($结果)? – 2012-02-15 22:09:12

+0

@yann:您在HAVING子句中测试的值必须等于数组中元素的数量。 – 2012-02-15 22:10:23

+0

如果没有特定项目的重复标签(换句话说,如果(item,tag)上有唯一约束)),那么您不需要'DISTINCT'。 – 2012-02-15 22:19:34

3

IN子句基本上只是写出长链or链的快捷方式。

... WHERE a IN (1,2,3) 

相同

... WHERE (a = 1) or (a = 2) or (a = 3) 

如果要求所有IN子句中值的存在,你不能用一个基本的IN子句。 MySQL中没有WHERE IN ALL (...)类型构造。

您可以使用子查询模拟它:

SELECT * 
FROM yourtable 
WHERE id IN (
    SELECT DISTINCT id 
    FROM yourtable 
    WHERE tag IN (1,3,123) 
    GROUP BY id 
    HAVING (COUNT(tag) = 3) 
); 

内部查询获取所有三个标签值都存在,再查询外层使用内部结果来获取完整记录所有ID。

+0

不应该'item'上的内部查询组,不是'id'? – 2012-02-15 22:25:53

1

SQL:

SELECT item FROM table WHERE tag IN (1,3,123) GROUP BY item HAVING COUNT(DISTINCT tag) = 3; 

PHP:

$query = sprintf('SELECT item FROM table WHERE tag IN (%s) GROUP BY item HAVING COUNT(DISTINCT tag) = %d', 
    implode(',', $results), 
    count($results));