列出尚未订购其他产品的客户

时间:2020-03-03 04:58:14

标签: mysql sql

这三个表是较大的订单管理系统的一部分:

 orders
o_id c_id
1    1
2    1
3    2
4    3
5    3
6    4
7    5


order_items
o_id  p_id
1     1
2     2
3     1
3     2
3     8
4     1
4     2
5     8
5     9
6     4
6     5
7    12

customers
c_id   name
1     Doug
2     Tammy
3     Bill
4     Don
5     Kate

我想找到所有对客户,其中该对客户中的第二个客户已购买了该对中第一位客户所没有购买的产品。我似乎无法弄清楚!我最好的尝试是获取所有独特产品的数量,并尝试利用该数量来进行分组和减少。

Expected Output
c_id1  c_id2
 4      1
 4      2
 4      3
 4      5
 5      1
 5      2
 5      3

或完全相反(无重复)。

CREATE TABLE orders (
  o_id      INT,
  c_id      INT
);

INSERT INTO orders (o_id, c_id) VALUES
(1, 1),
(2, 1),
(3, 2), 
(4, 3),
(5, 3),
(6, 4),
(7, 5);

CREATE TABLE order_items (
  o_id      INT,
  p_id      INT
);

INSERT INTO order_items (o_id, p_id) VALUES
(1, 1),
(2, 2),
(3, 1), 
(3, 2),
(3, 8),
(4, 1),
(4, 2),
(5, 8),
(5, 9),
(6, 4),
(6, 5),
(7, 12);

CREATE TABLE customers (
  c_id      INT,
  name      VARCHAR(10)
);

INSERT INTO customers (c_id, name) VALUES
(1, 'Doug'),
(2, 'Tammy'),
(3, 'Bill'), 
(4, 'Don'),
(5, 'Kate');

2 个答案:

答案 0 :(得分:0)

测试

WITH cte AS ( SELECT *
              FROM orders
              NATURAL JOIN order_items
              NATURAL JOIN customers )
SELECT t1.c_id id1, t2.c_id id2
FROM customers t1
JOIN customers t2 ON t1.c_id < t2.c_id 
WHERE NOT EXISTS ( SELECT NULL
                   FROM cte cte1, cte cte2
                   WHERE cte1.c_id = t1.c_id
                     AND cte2.c_id = t2.c_id
                     AND cte1.p_id = cte2.p_id );

fiddle

答案 1 :(得分:0)

该想法是(使用cross join生成所有成对的客户。

然后检查它们是否没有相同的项目。这有点棘手,但是涉及not exists并加入到商品级别,以查看是否有与客户匹配的订单中有匹配的商品:

select c1.c_id, c2.c_id
from customers c1 cross join
     customers c2
where not exists (select 1
                  from order_items oi1 join
                       order_items oi2
                       on oi1.i_id = oi2.i_id join
                       orders o1
                       on o1.o_id = oi1.o_id join
                       orders o2
                       on o2.o_id = oi2.o_id
                  where o1.c_id = c1.c_id and
                        o2.c_id = o2.c_id
                 );