如果发现行,MySQL在表上相交,否则忽略

时间:2018-06-26 19:25:41

标签: mysql sql logic

我一直在使用下表列出的数据库:

Customer
id    INTEGER, PRIMARY KEY
name  VARCHAR

Entrance
id    INTEGER, PRIMARY KEY
desc  VARCHAR

CustomerEntranceRestriction
idEntrance PK, FK to Entrance.id
idCustomer PK, FK to Customer.id

CustomerEntranceRestriction表仅包含客户只能使用其入口的条目。此表中没有记录的客户可以访问任何入口。

我想尝试并退回每个客户可以访问的所有入口。我的查询如下:

SELECT DISTINCT 
   c.id As customer_id, 
   e.id AS entrance_id 
FROM customer c 
JOIN entrance e 
LEFT JOIN CustomerEntranceRestriction cer1 
  ON cer1.idCustomer = cu.id 
LEFT JOIN CustomerEntranceRestriction cer2
  ON cer2.idEntrance = e.id 
WHERE   
   IF(cer1.idCustomer IS NULL, 0, cer2.idEntrance - e.id) = 0 
AND   
   IF(cer2.idEntrance IS NOT NULL,IF(cer2.idCustomer =cu.idCustomer,0,1),0) = 0

我认为这是正确的,但是我对逻辑只有一个松散的理解。通过在部分主键上两次左键连接到CustomerEntranceRestriction表上,我们可以包含两个匹配都具有NULL值的行。在cer1cer2上发生匹配的地方,我们检查是否与c.ide.id匹配,并删除失败的行。

这是合理的逻辑吗?我不确定这在关系数据库圈子中是否有名称。

另一种方法是对CustomerEntrance中没有客户的所有CustomerEntranceRestrctionUNION记录进行交叉联接1}}表。

任何建议将不胜感激。

2 个答案:

答案 0 :(得分:1)

我想你想要

SELECT c.id As customer_id, 
       e.id AS entrance_id 
FROM customer c CROSS JOIN
     entrance e LEFT JOIN
     CustomerEntranceRestriction cer
     ON cer.idCustomer = c.id AND cer.idEntrance = e.id 
WHERE NOT EXISTS (SELECT 1 FROM CustomerEntranceRestriction cer2 WHERE cer2.idCustomer = c.idCustomer) OR
      cer.idEntrance IS NOT NULL;

这始于客户和入口的所有组合。然后带来了任何限制。

WHERE子句说(1)客户没有任何限制,或者(2)客户可以进入此特定入口。

答案 1 :(得分:0)

要使用代码,您可以避免使用if条件,而只需使用正确的where和AND

  SELECT DISTINCT 
     c.id As customer_id, 
     e.id AS entrance_id 
  FROM customer c 
  JOIN entrance e 
  LEFT JOIN CustomerEntranceRestriction cer1 
    ON cer1.idCustomer = cu.id 
  LEFT JOIN CustomerEntranceRestriction cer2
    ON cer2.idEntrance = e.id 
  WHERE   cer1.idCustomer IS NULL
  AND   cer2idEntrance IS NOT NULL AND cer2.idCustomer = cu.idCustomer