13

私はこのクエリに苦労しています。私は2つのテーブルを持っています。クーポンと請求書番号のあるもの。請求書番号と顧客名が記載されたもの。

特定のクーポンを使用していない顧客を取得する必要があります。

ここにテーブルがあります:

プロモーション テーブル:

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

注文表:

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

ジャックはクーポン A と B を使用しました。ジルはクーポン B のみを使用しました。

私のクエリがクーポン A を使用していない選択された顧客である場合、ジルを取得する必要があります。

これは機能しますが、不器用で遅いようです。より良い方法はありますか?

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

更新:簡単に実行できる場合は、パフォーマンスを向上させるために、prefer to use joins を使用する必要があります。結合とサブクエリ

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;

注: 2 つの結合されたテーブルの列名は異なる必要があるため、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;

2 番目のステップ:

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'));

編集クエリを高速化するために個別を追加しました

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

代わりに次のクエリを試してください。

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')

アイデアはGROUP BY、クエリの上部にある結合を削除して を取り除き、調整されたサブクエリNOT INを作成して を排除することです。

ここに 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 に答える