如何在具有多个联接的m:n关系中获得多个条件?

时间:2019-06-25 13:51:10

标签: mysql

我必须编写一个复杂的查询才能在MySQL中获得具有多种条件的产品,并停留在具有多种条件的关系上。

数据库结构是从Typo3构建的。目前,我有4个具有多个条件的联接。一切工作正常,但我的SQL的最后一行是问题。但是我找不到任何解决办法。

SELECT p.uid
FROM tx_myext_domain_model_product p
         JOIN tx_myext_domain_model_productwirkung w
              ON p.uid = w.product
         JOIN sys_category_record_mm ck
              ON p.uid = ck.uid_foreign
         JOIN sys_category_record_mm cc
              ON p.uid = cc.uid_foreign
         JOIN sys_category_record_mm cw
              ON w.uid = cw.uid_foreign
WHERE p.season IN(1,'')
  AND p.type = "herbizid"
  AND ck.uid_local = 2
  AND ck.tablenames = "tx_myext_domain_model_product"
  AND ck.fieldname = "culture"
  AND cc.tablenames = "tx_myext_domain_model_product"
  AND cc.fieldname = "chemicals"
  AND cw.tablenames = "tx_myext_domain_model_productwirkung"
  AND cw.uid_local IN (2, 395, 257)  
  AND w.grad = 6;

#  and wirkung with cw.uid_local = 2 should have w.grad = 6
#  and wirkung with cw.uid_local = 395 should have w.grad = 6  
#  and wirkung with cw.uid_local = 257 should have w.grad in range from 1 to 6

“ productwirkung”应具有类别2、395和257,而“ productwirkung”应具有类别2和395。

我知道,在最后一行中,我什么也没得到...

编辑

我不能添加w.grad = 6,因为该产品也应具有1级至6级的257类productwirkung。一种产品与productwirkung有多种关系。因此,如果有一个产品等级为6的productwirkung 2,等级为6的productwirkung 395,等级为3的productwirkung 257,我想要这个产品。如果我要求... cw.uid_local IN (2, 395, 257) AND w.grad = 6,则不会选择该产品,因为productwirkung 257没有w.grad = 6。

3 个答案:

答案 0 :(得分:2)

假设uid_local是唯一的,则定义不能同时为2395

我想你想参加

  ...
  AND ((`cw`.`uid_local` = 2 AND `w`.`grad` = 6) OR (`cw`.`uid_local` = 395 AND `w`.`grad` = 6));

编辑

由于在两个子表达式中都检查了w.grad = 6,所以这可能也简化为

  ...
  AND w.grad = 6
  AND (cw.uid_local = 2 OR cw.uid_local = 395)

甚至进一步简化为

  ...
  AND w.grad = 6
  AND cw.uid_local IN (2, 395)

答案 1 :(得分:0)

如果我们重写您的查询,除其他外,我们将获得以下信息:

AND cw.uid_local = 2 
AND cw.uid_local = 395 

除非uid_local处于某种量子状态,否则这不太可能成功。

FWIW,我觉得这个(略)更容易阅读...

SELECT p.uid
  FROM tx_myext_domain_model_product p
  JOIN tx_myext_domain_model_productwirkung w
    ON p.uid = w.product
  JOIN sys_category_record_mm ck
    ON p.uid = ck.uid_foreign
  JOIN sys_category_record_mm cc
    ON p.uid = cc.uid_foreign
  JOIN sys_category_record_mm cw
    ON w.uid = cw.uid_foreign
 WHERE p.season IN(1,'')
   AND p.type = "herbizid"
   AND ck.uid_local = 2
   AND ck.tablenames = "tx_myest_domain_model_product"
   AND ck.fieldname = "culture"
   AND cw.uid_local IN (2, 395, 257)
   AND cw.tablenames = "tx_myext_domain_model_productwirkung"
   AND cc.tablenames = "tx_myext_domain_model_product"
   AND cc.fieldname = "chemicals"
   AND w.grad = 6;

答案 2 :(得分:0)

您的问题是您的最后两个条件相互矛盾。他们声明,行必须包含2、395或257个cw.uid_local,并且 AND 的ID必须为2 AND 395在一行中。如果您将最后两行重写为OR条件,则应获得所需的结果:

SELECT `p`.`uid`
FROM `tx_myext_domain_model_product` `p`
     INNER JOIN `tx_myext_domain_model_productwirkung` `w`
                ON `p`.`uid` = w.product
     INNER JOIN `sys_category_record_mm` `ck`
                ON `ck`.`tablenames` = "tx_myest_domain_model_product"
                    AND `p`.`uid` = ck.uid_foreign
                    AND `ck`.`fieldname` = "culture"
     INNER JOIN `sys_category_record_mm` `cc`
                ON `cc`.`tablenames` = "tx_myext_domain_model_product"
                    AND `p`.`uid` = cc.uid_foreign
                    AND `cc`.`fieldname` = "chemicals"
     INNER JOIN `sys_category_record_mm` `cw`
                ON `cw`.`tablenames` = "tx_myext_domain_model_productwirkung"
                    AND `w`.`uid` = cw.uid_foreign
WHERE ((`p`.`season` = "1") OR (`p`.`season` = ""))
  AND (`p`.`type` = "herbizid")
  AND (`ck`.`uid_local` = "2")
  AND ((`cw`.`uid_local` IN (2, 395) AND `w`.`grad` = 6) OR `cw`.`uid_local` = 257);

编辑

在阅读您的编辑内容后,我认为最好为子查询提供服务,因为对于单个查询,您的要求条件存在冲突。

如果您希望满足 ALL 条件的产品(带有“ children”的产品(uid_local为2且等级为6)具有 AND “ children” (uid_local为395 AND等级6) AND “子项”(uid_local为257 AND等级1至6之间)),我建议对子查询使用内部联接将数据限制为“ children”情况”:

SELECT DISTINCT p.uid
FROM tx_myext_domain_model_product p
  ### WHERE cw.uid_local = 2 AND w.grad = 6
  JOIN (
    SELECT p_1.uid
    FROM tx_myext_domain_model_product p_1
    JOIN tx_myext_domain_model_productwirkung w_1
      ON p_1.uid = w_1.product
    JOIN sys_category_record_mm cw_1
      ON w_1.uid = cw_1.uid_foreign
    WHERE cw_1.tablenames = "tx_myext_domain_model_productwirkung"
      AND cw_1.uid_local = 2
      AND w_1.grad = 6
  ) p1 ON p1.uid = p.uid
  ### WHERE cw.uid_local = 395 AND w.grad = 6
  JOIN (
    SELECT p_2.uid
    FROM tx_myext_domain_model_product p_2
    JOIN tx_myext_domain_model_productwirkung w_2
      ON p_2.uid = w_2.product
    JOIN sys_category_record_mm cw_2
      ON w_2.uid = cw_2.uid_foreign
    WHERE cw_2.tablenames = "tx_myext_domain_model_productwirkung"
      AND cw_2.uid_local = 395
      AND w_2.grad = 6
  ) p2 ON p2.uid = p.uid
  ### WHERE cw.uid_local = 257 AND w.grad BETWEEN 1 AND 6
  JOIN (
    SELECT p_3.uid
    FROM tx_myext_domain_model_product p_3
    JOIN tx_myext_domain_model_productwirkung w_3
      ON p_3.uid = w_3.product
    JOIN sys_category_record_mm cw_3
      ON w_3.uid = cw_3.uid_foreign
    WHERE cw_3.tablenames = "tx_myext_domain_model_productwirkung"
      AND cw_3.uid_local = 257
      AND w_3.grad BETWEEN 1 AND 6
  ) p3 ON p3.uid = p.uid
  JOIN tx_myext_domain_model_productwirkung w
    ON p.uid = w.product
  JOIN sys_category_record_mm ck
    ON p.uid = ck.uid_foreign
  JOIN sys_category_record_mm cc
    ON p.uid = cc.uid_foreign
  JOIN sys_category_record_mm cw
    ON w.uid = cw.uid_foreign
WHERE p.season IN(1,'')
  AND p.type = "herbizid"
  AND ck.uid_local = 2
  AND ck.tablenames = "tx_myest_domain_model_product"
  AND ck.fieldname = "culture"
  AND cc.tablenames = "tx_myext_domain_model_product"
  AND cc.fieldname = "chemicals";