13

我一直在努力解决这个问题。我有两张桌子。一张带有优惠券和发票号码。一种带有发票编号和客户姓名。

我需要获取没有使用给定优惠券的客户。

以下是表格:

促销表:

Promotions
Invoice | Coupon
----------------
1       | couponA
2       | couponB
3       | couponB

订单表:

Orders
Invoice | Customer
------------------
1       | Jack
2       | Jack
3       | Jill

所以杰克使用了优惠券 A 和 B。而吉尔只使用了优惠券 B。

如果我的查询是选择没有使用优惠券 A 的客户,我应该得到 Jill。

这行得通,但它似乎笨拙和缓慢。有没有更好的办法?

SELECT Customer 
FROM Promotions INNER JOIN Orders
ON Promotions.Invoice = Orders.Invoice
WHERE Customer NOT IN(
    SELECT Customer 
    FROM Promotions INNER JOIN Orders
    ON Promotions.Invoice = Orders.Invoice
    WHERE Coupon = couponA)
GROUP BY Customer

感谢您的关注!

编辑:这是一个 SQLFiddle 架构 http://sqlfiddle.com/#!2/21d31/6

4

4 回答 4

5

更新:当它对我们来说很容易做时,我们应该使用更喜欢使用连接以获得更好的性能。加入与子查询

Sql 小提琴

Select distinct Customer from orders o
join 
(
  SELECT distinct Customer as changedname FROM Orders o2 
  join
  (
     Select distinct invoice from Promotions where Coupon='couponA'
  ) t3
  on o2.invoice = t3.invoice      
) t2
on o.customer != t2.changedname;

注意:我为 t3 更改了列名 customer,因为两个连接表必须具有不同的列名

解释:

当您拥有大数据时,使用内部或子查询会很昂贵。改为使用连接,让我们学习将子查询转换为连接

使用子查询我们有:

Select distinct Customer from orders where customer not in 
(SELECT distinct Customer FROM Orders where invoice in
(Select distinct invoice from Promotions where Coupon='couponA'));

将子查询转换为加入

第一步:

Select distinct Customer from orders o
join 
(
  SELECT distinct Customer as changedname FROM Orders where invoice in
  (Select distinct invoice from Promotions where Coupon='couponA')
) t2
on o.customer != t2.changedname;

第二步:

Select distinct Customer from orders o
join 
(
  SELECT distinct Customer as changedname FROM Orders o2 where invoice 
  join
  (
     Select distinct invoice from Promotions where Coupon='couponA'
  ) t3
  on o2.invoice = t3.invoice      
) t2
on o.customer != t2.changedname;

就是这样,对于有很多行的表来说要快得多

原答案:

使用not in. 看一看。

Select distinct Customer from orders where customer not in 
(SELECT distinct Customer FROM Orders where invoice in
(Select distinct invoice from Promotions where Coupon='couponA'));

编辑我添加了 distinct 以使查询更快

SQL小提琴

于 2012-12-24T07:30:03.450 回答
4
 SELECT DISTINCT o2.customer FROM ORDER o2 
LEFT JOIN (promotions p1 
    JOIN Orders o1 ON p1.cuopon = 'CuoponA' AND p1.invoice = o1.invoice ) p3 
    ON o2.customer = p3.customer 
WHERE p3.customer IS NULL
于 2012-12-24T06:56:25.703 回答
1

Try this query instead:

SELECT DISTINCT Customer
FROM Orders o1
WHERE NOT EXISTS (
    SELECT 1 
    FROM Orders o2
    INNER JOIN Promotions ON Promotions.Invoice = o2.Invoice
    WHERE o1.Customer = o2.Customer AND Coupon = 'couponB')

The idea is to get rid of the GROUP BY by removing a join in the top part of the query, and also eliminate the NOT IN by making a coordinated subquery.

Here is a link to sqlfiddle.

于 2012-12-24T05:30:07.693 回答
0

用正确的连接试试这个

SELECT Customer, Coupon
FROM Promotions 
RIGHT JOIN Orders ON Promotions.Invoice = Orders.Invoice
    AND Coupon = 'couponA'
GROUP BY Customer
HAVING Coupon IS NULL
于 2012-12-24T05:44:32.783 回答