MySQL пересекается в таблице, если строки найдены, и игнорирует в противном случае - PullRequest
0 голосов
/ 26 июня 2018

Я работал над базой данных с таблицами, перечисленными ниже:

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.id или e.id, удаляя те строки, где это не удается.

Это логика звука? Я не уверен, есть ли у этого имя в кругах реляционных баз данных.

Альтернативный подход заключается в перекрестном объединении всех записей Customer и Entrance, которые не имеют клиентов в CustomerEntranceRestrction и UNION тех записях, которые найдены в таблице CustomerEntranceRestriction.

Будем благодарны за любые предложения.

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Я думаю, что вы хотите:

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) этот конкретный вход разрешен для клиента.

0 голосов
/ 26 июня 2018

Глядя на свой код, вы можете избежать условия 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...