Я думаю, я бы начал с подзапроса, который генерирует (непересекающееся) объединение:
- Идентификатор компании и (ненулевое) количество пользователей, которые могут получить доступ к системе, где хотя бы один пользователь может получить доступ к системе
- Идентификатор компании и нулевой счет, когда ни один пользователь не может получить доступ к системе
Предполагая, что User.CanAccessSystem IS NULL
был артефактом, необходимым для учета ЛЕВОГО СОЕДИНЕНИЯ, что приводит к:
SELECT Company.ID, COUNT(*) AS UserCount
FROM Company, User
WHERE Company.ID = User.CompanyID
AND User.CanAccessSystem = true
UNION
SELECT Company.ID, 0 AS UserCount
FROM Company
WHERE NOT EXISTS (SELECT * FROM User
WHERE Company.ID = User.CompanyID
AND User.CanAccessSystem = true)
Вы можете отфильтровать обе части с помощью 'AND Company.CanAccessSystem = true', и будет полезно, если большинство компаний не смогут получить доступ к системе - или вы можете отложить ее до финальной стадии обработки.
Затем необходимо выполнить прямое объединение этого результата с Компанией, обеспечив, чтобы условие фильтра для компании, имеющей доступ к системе, было применено где-то вдоль линии.
Номинально это приводит к следующему (непроверенному) коду:
SELECT UserCount, Company.*
FROM Company JOIN
(SELECT Company.ID AS ID, COUNT(*) AS UserCount
FROM Company, User
WHERE Company.ID = User.CompanyID
AND User.CanAccessSystem = true
UNION
SELECT Company.ID AS ID, 0 AS UserCount
FROM Company
WHERE NOT EXISTS (SELECT * FROM User
WHERE Company.ID = User.CompanyID
AND User.CanAccessSystem = true)
) AS NumUsers
ON Company.ID = NumUsers.ID
WHERE Company.CanAccessSystem = true