自连接以查找不在项目(采购)中的客户 ID

Self-join to find Customers IDs not in Item (Purchase)

我有一个包含两列的 table:ProductID 和 CustomerID

每次特定客户 (CustomerID) 购买特定产品(由特定 ProductID 表示)时,table 都会记录下来。

ProductID 可以出现多次,与不同的 customerID 匹配(客户可能会多次购买产品)。

ProductID CustomerID
1111111 14567
2222222 17890
3333333 17890
4444444 17890
5555555 14567
5555555 17890

有没有办法两个拉出购买了某种产品(ProductID)但没有购买另一种产品(ProductID)的客户(CustomerID)。

目前,我有

select a.CustomerID
from iread a, iread b
where a.CustomerID in ({{ProductID}}) and b.CustomerID not in ({{ProductID}})
and a.CustomerID=b.CustomerID

这让我返回了 ProductID...我认为这可能与这部分有关:

where a.CustomerID in ({{ProductID}}) and b.CustomerID not in ({{ProductID}})

任何 help/solutions 欢迎!谢谢!!

使用 having 子句和 case 表达式来过滤聚合记录将帮助您过滤多行。这也比自加入更便宜。

例如

SELECT
    CustomerID
FROM
    iread
WHERE 
    ProductID IN (<included_comma_separated_product_ids_to_be_considered_which_are_desired_and_not_desired>)
GROUP BY
    CustomerID
HAVING
    SUM(
        CASE WHEN ProductID=<include_desired_product_id> THEN 1 ELSE 0 END
    ) > 0 AND
    SUM(
        CASE WHEN ProductID=<include_not_desired_product_id> THEN 1 ELSE 0 END
    ) = 0

下面是一个示例,我们尝试根据您共享的示例数据查找购买了 5555555 但未购买 1111111 的客户。

用于调试目的的聚合结果

SELECT
    CustomerID,
    SUM(
        CASE WHEN ProductID=5555555 THEN 1 ELSE 0 END
    ) as desired_product,
    SUM(
        CASE WHEN ProductID=1111111 THEN 1 ELSE 0 END
    ) as undesired_product
FROM
    iread
WHERE 
    ProductID IN (5555555,1111111)
GROUP BY
    CustomerID;
CustomerID desired_product undesired_product
14567 1 1
17890 1 0

使用 Having 和 Case 表达式检索所需的客户

SELECT
    CustomerID
FROM
    iread
WHERE 
    ProductID IN (5555555,1111111)
GROUP BY
    CustomerID
HAVING
    SUM(
        CASE WHEN ProductID=5555555 THEN 1 ELSE 0 END
    ) > 0 AND
    SUM(
        CASE WHEN ProductID=1111111 THEN 1 ELSE 0 END
    ) = 0;
CustomerID
17890

View working demo on DB Fiddle

编辑 1: 我修改了上面的示例以包含 where 子句。如果索引在 table.

上可用,这应该利用 where 子句中使用的列上的索引

让我知道这是否适合你。