如果找到行,MySQL 在表上相交,否则忽略

标签 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 的行两个匹配的值。当匹配发生在 cer1 上时或cer2我们检查是否有匹配 c.ide.id ,删除失败的行。

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

另一种方法是交叉连接所有 CustomerEntrance CustomerEntranceRestrction 中没有客户的记录和UNION这些记录在 CustomerEntranceRestriction 中找到表。

如有任何建议,我们将不胜感激。

最佳答案

我想你想要:

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) 允许客户进入此特定入口。

关于如果找到行,MySQL 在表上相交,否则忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51050115/

相关文章:

mysql - 如果记录存在于多个表中则更新 SQL 查询

php - 从 mysql 选择多行,但显示每个 id 的一个结果

mySQL 复合主键,部分键自增

mysql - SQL 季度总计和增长百分比前十名

sql - Postgres : join if field is not null in both tables?

php - 寻找最佳解决方案所需的算法逻辑

algorithm - 如何获得可以使用给定数字组成的所有可能的 n 位数字?

PHP 更新现有 MySQL 行或插入新行(对 UPDATE ON DUPLICATE KEY 感到困惑)

java - 从数据库填充 JTree

c++ - 仅处理逻辑的 C/C++ HTTP 库?