我目前正在研究通过多到任意关系链接的对象(这意味着许多对象可以链接到。。。同一类型的对象不多,但类型可能不同的对象很多)。
但是,对于这个问题,多对多就足够了。
所以,假设我有一个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返回与ObjectA子句匹配的所有WHEREs。至于关系条件,您必须计算匹配的行:

  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

关于mysql - MySQL从多对多关系中过滤许多元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25015710/

10-09 10:02