[英]MySQL filter many elements from many-to-many relationship
我目前正在处理通过多对多关系链接的对象(这意味着可以将许多对象链接到...相同类型的对象不多,但类型可以变化的对象也很多)。
但是,对于这个问题,多对多就足够了。
因此,假设我有一个ObjectA表,其中包含以下内容:
CREATE TABLE (
id INT(11) NOT NULL,
label VARCHAR(30) NOT NULL,
-- primary keys and all the stuff
);
CREATE TABLE ObjectB (
id INT(11) NOT NULL,
label VARCHAR(30) NOT NULL,
-- primary keys and all the stuff
);
CREATE TABLE ObjectA_ObjectB (
objectA_id INT(11) NOT NULL,
objectA_type VARCHAR(250) NOT NULL, -- for the many to any
objectB_id INT(11) NOT NULL,
-- primary keys and all the stuff
);
假设我要用ObjectB中的2个或3个元素过滤ObjectA。 您会认为我应该使用IN
:
SELECT *
FROM ObjectA a
LEFT JOIN ObjectA_ObjectB relation ON a.id = relation.objectA_id AND "ObjectA" = relation.objectA_class
LEFT JOIN ObjectB b ON relation.objectB_id = b.id
WHERE b.id IN (1, 2, 3);
但是,问题是,通过此请求,它获取与至少一个搜索到的ObjectB(此处为1、2和3)链接的所有objectAs。 但是,我想要的是那些具有所有 ObjectB的1、2和3的对象。
我已经尝试了一些方法(例如ALL
可能性,或者正在考虑在SQL之外进行第一个过滤器),但是并没有得到预期的结果。
有任何想法吗 ?
综上所述,我希望能够像GitHub上的问题以及它们如何过滤标签那样做。 如果拾取一堆标签,则仅返回具有所有选定标签的问题,而不是具有至少一个标签的所有问题。
谢谢 !
从您的评论看来,您不希望LEFT JOIN
将返回与WHERE
子句匹配的所有ObjectA
。 至于关系条件,您必须计算匹配的行:
SELECT *
FROM ObjectA a
JOIN ObjectA_ObjectB relation
ON a.id = relation.objectA_id
AND "ObjectA" = relation.objectA_class
JOIN ObjectB b
ON relation.objectB_id = b.id
GROUP BY a.id
HAVING COUNT(CASE WHEN b.id IN (1,2,3) THEN 1 ELSE NULL END)=3;
要么:
SELECT *
FROM ObjectA a
JOIN ObjectA_ObjectB relation
ON a.id = relation.objectA_id
AND "ObjectA" = relation.objectA_class
JOIN ObjectB b
ON relation.objectB_id = b.id
AND b.id IN (1,2,3)
GROUP BY a.id
HAVING COUNT(*)=3;
如果您实际上在此查询中不需要ObjectB数据,则可以进一步简化此操作:
SELECT a.*
FROM ObjectA a
JOIN ObjectA_ObjectB relation
ON a.id = relation.objectA_id
AND "ObjectA" = relation.objectA_class
AND relation.objectB_id IN (1,2,3)
GROUP BY a.id
HAVING COUNT(*)=3;
这是假设你只能各有一个ObjectB.id
链接到一个ObjectA
通过透视表。
一种解决方案是在Have子句中计算匹配条件。
SELECT *
FROM ObjectA a
JOIN ObjectA_ObjectB relation ON a.id = relation.objectA_id AND "ObjectA" = relation.objectA_class
JOIN ObjectB b ON relation.objectB_id = b.id
WHERE b.id IN (1, 2, 3) GROUP BY a.id HAVING COUNT(b.id)=3;
请参见sqlfidle示例 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.