我正在使用MYSQL 5.X,但无法确定查询;

我有2个具有多对多关系的实体。

客户和服务,因此我有3个表:

客户,clients_has_services和服务。

我需要选择与特定客户端无关的所有服务。

例如:
我有ID为1的客户端,总共有4个服务(Service1,Service2,Service3,Service4),客户端1与Service1有关系,因此我需要检索所有其他服务(Service2,Service3,Service4)

有什么建议吗?

最佳答案

首先,获取所有services的集合。

将其加入clients中的“特定客户端”行,这样就可以为客户端提供一组所有服务。

“技巧”是使用反联接模式来排除在clients_have_services表中具有“匹配项”的行。

如果您具有该客户端的唯一标识符(并且只需要一个客户端的列表),则类似于以下内容:

SELECT s.*
  FROM services s
  LEFT
  JOIN clients_have_services h
    ON h.service_id = s.id
   AND h.client_id = 42
 WHERE h.service_id IS NULL
 ORDER BY s.id


外部联接返回services中的所有行以及clients_have_services表中的所有“匹配”行。 “技巧”是WHERE子句中的谓词,它排除找到匹配项的任何行,仅保留与特定客户端无关的services

如果要为多个客户执行此操作,则还需要返回与服务交叉连接的客户(作为客户和服务的交叉产品),然后排除匹配项。

例如:

SELECT c.id AS client_id
     , s.*
  FROM clients c
 CROSS
  JOIN services s
  LEFT
  JOIN clients_have_services h
    ON h.service_id = s.id
   AND h.client_id = c.id
 WHERE h.service_id IS NULL
 ORDER BY c.id, s.id




还有其他两种查询模式将返回等效结果,例如,NOT EXISTS

SELECT s.*
  FROM services s
 WHERE NOT EXISTS
       ( SELECT 1
           FROM clients_have_services h
          WHERE c.client_id = 42
            AND h.service_id = s.id
       )
 ORDER BY s.id

10-06 07:44