我有一个包含许多表的数据库:
customer
------
id
name
customer_order
------
order_id
order_cost
customer_id
customer_order_line
------
order_line_id
order_id
order_line_product_id
product
------
product_id
product_name
product_cost
我想要做的是选择所有没有购买某个特定商品的顾客,例如,如果我输入“apple”作为要输入的变量,我想要退回所有尚未购买苹果的顾客。
这只是一个场景。
我花了几天时间尝试这样做,例如将所有产品连接到一个字段并使用NOT LIKE @searchVariable
但我似乎无法使其工作,因为它始终考虑来自customer_order_line
表的所有记录。
有人能指出我正确的方向吗?
干杯
有几种方法可以解决这个问题。这是一个使用not exists
:
select *
from customer c
where not exists (
select 1
from customer_order co
join customer_order_line col on co.order_id = col.order_id
join product p on p.product_id = p.order_line_product_id
where c.id = co.customer_id
and p.product_name = 'Apple'
)
有时回答这个问题的最简单方法就是把它转过头来。您如何找到订购苹果的所有客户?那很简单......
SELECT cusomer_id
FROM customer_order co
INNER JOIN customer_order_line col
ON co.order_id = col.order_id
INNER JOIN product p
ON col.order_line_product_id = p.product_id
WHERE p.product_name = 'apple'
然后,它只是找到列出NOT IN
的所有客户的情况
SELECT *
FROM customer
WHERE id NOT IN (
SELECT cusomer_id
FROM customer_order co
INNER JOIN customer_order_line col
ON co.order_id = col.order_id
INNER JOIN product p
ON col.order_line_product_id = p.product_id
WHERE p.product_name = 'apple'
)
还有很多其他(可能更有效)的方法可以做到这一点,但希望这会让你走上正轨。
这是另一种方式:
select co.name, count(*)
from customer_order co
left join join customer_order_line col on co.order_id = col.order_id
left join product p on p.product_id = p.order_line_product_id
where p.product_name = 'Apple'
group by co.name
having count(*) = 0;