自连接以查找不在项目(采购)中的客户 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 子句中使用的列上的索引
让我知道这是否适合你。
我有一个包含两列的 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 子句中使用的列上的索引让我知道这是否适合你。