在我的查询中,我使用连接表category_attributes
。我们假设我们有这样的行:
category_id|attribute_id
1|1
1|2
1|3
我想要满足以下两个需求的查询。我有一个允许attribute_id's
的变量(php)。如果数组是attribute_id
的子集,那么应该选择category_id
,如果不是 - 没有结果。
第一种情况:
select * from category_attributes where (1,2,3,4) in category_attributes.attribute_id
应该没有结果。
第二种情况
select * from category_attributes where (1,2,3) in category_attributes.attribute_id
应该给所有三行(参见开头的虚拟行)。
所以我想反对标准SQL in
所做的事情。
步骤1:按要检查的字段对数据进行分组。
步骤2:左边连接所需值列表和上一步中获得的记录。
第3步:现在我们有一个列表,其中包含表中所需的值和相应的值。如果第二列存在于表中,则第二列将等于所需值,否则将为NULL
。
在右列中计算空值。如果它等于0,则表示表包含所有必需的值。在这种情况下,返回表中的所有记录。否则,表中必须至少缺少一个必需值。所以,不返回任何记录。
表“数据”:
所需值:
10, 20, 50
查询:
SELECT *
FROM Data
WHERE (SELECT Count(*)
FROM (SELECT D.value
FROM (SELECT 10 AS value
UNION
SELECT 20 AS value
UNION
SELECT 50 AS value) T
LEFT JOIN (SELECT value
FROM Data
GROUP BY value) D
ON ( T.value = D.value )) J
WHERE value IS NULL) = 0;
你可以使用group by
和having
:
select ca.category_id
from category_attributes ca
where ca.attribute_id in (1, 2, 3, 4)
group by ca.category_id
having count(*) = 4; -- "4" is the size of the list
这假定表没有重复项(这是属性映射表的典型表)。如果可能,请使用:
having count(distinct ca.attribute_id) = 4
你可以将attribute_id
聚合到数组中并比较来自php的两个数组。
SELECT category_id FROM
(select category_id, group_concat(attribute_id) as attributes from category_attributes
order by attribute_id) t WHERE t.attributes = (1, 2, 3);
但是您需要找到另一种方法来比较数组或确保数组始终排序。