SQL检测1:M和M:M之间的不一致关系

时间:2014-05-31 20:28:54

标签: python sql django postgresql

我在Django应用程序中有四个表,由PostgreSQL DB支持:

  • 客户
  • SalesOrder
  • 用户组
  • CustomerToUserGroupMembership

从SalesOrder到UserGroup有一个标准外键,Customer和UserGroup之间有一个M:M关系。所有表都有uuid列,充当PK。

最终,我正在尝试使用快速SQL查询查找订单,该查询将以Python条件表示为order.userGroup not in order.customer.userGroups.all()

我尝试过类似的事情:

SELECT o.uuid 
FROM myapp_salesorder o JOIN myapp_customer c ON o.customer_id = c.uuid
WHERE o."userGroup_id" NOT IN (
    SELECT m."userGroup_id" FROM myapp_customertousergroupmembership m 
    WHERE m.customer_id = c.uuid
);

...但是子选择确实减慢了速度。

有没有更好的方法来制作它以加快速度?

1 个答案:

答案 0 :(得分:1)

有不同的方法。对于您的情况,我会使用not exists

SELECT o.uuid 
FROM myapp_salesorder o JOIN
     myapp_customer c
     ON o.customer_id = c.uuid
WHERE NOT EXISTS (SELECT 1
                  FROM myapp_customertousergroupmembership m 
                  WHERE m.customer_id = c.uuid AND m.userGroup_id = o.userGroup_id
                 );

为获得最佳性能,请在myapp_customertousergroupmembership(customer_id, userGroup_id)上创建复合索引。

编辑:

join版本很简单:

SELECT o.uuid 
FROM myapp_salesorder o JOIN
     myapp_customer c
     ON o.customer_id = c.uuid LEFT JOIN
     myapp_customertousergroupmembership m
     ON m.customer_id = c.uuid AND m.userGroup_id = o.userGroup_id
WHERE m.customer_id IS NULL;

但我不知道表现是否会更好。