如何编写从 LEFT JOIN 结果中减去 INNER JOIN 结果的 SQL 查询?
How to write a SQL query that subtracts INNER JOIN results from LEFT JOIN results?
举个例子:我想看看我的营销工作对我想在商店里销售的产品的效果如何。例如,我想知道有多少人在 2014 年 12 月 1 日的电子邮件中收到优惠券后一个月内购买了我的产品,相比之下有多少人在同一时间段内购买了我的产品而从未收到过优惠券优惠券。
这是我的客户示例 table:
CUSTOMER_NUMBER PURCHASE_DATE
--------------- -------------
1 2014-12-02
2 2014-12-05
3 2014-12-05
4 2014-12-10
5 2014-12-21
这是我的电子邮件示例 table
CUSTOMER_NUMBER EMAIL_ADDR SEND_DATE
--------------- ------------ ----------
1 john@abc.com 2014-12-01
3 mary@xyz.com 2014-12-01
5 beth@def.com 2014-12-01
我很清楚如何确定谁用优惠券购买了产品:我在两个 table 上使用内部联接。但是为了确定谁购买了产品,即使他们出于某种原因没有优惠券(他们没有电子邮件,他们是对照组的一部分,等等),我 think 我需要用left join得到一个结果集,然后从我的第一个结果集中减去inner join的结果。 las,这就是我被困的地方。在上面的示例中,客户 2 和 5 购买了产品,即使他们从未收到过优惠券,但我不知道如何为 return 该数据编写查询。
我正在使用 IBM 的 Netezza 数据库。谢谢!!
使用 Left Outer Join
和 NULL
检查
SELECT C.*
FROM customer C
LEFT OUTER JOIN email e
ON C.customer_Number = E.customer_Number
WHERE E.customer_Number IS NULL
或使用Not Exists
SELECT *
FROM customer C
WHERE NOT EXISTS (SELECT 1
FROM email e
WHERE c.customer_number = e.customer_number)
select from customers c left outer join email e
on c.customer_number = e.customer_number
where e.customer_number is null
or C.purchase_date < e.send_date
SELECT
C.*,
PurchasedWithin30DaysOfEmailedCoupon =
CASE WHEN EXISTS (
SELECT *
FROM
Email E
WHERE
C.CustomerID = E.CustomerID
AND C.Purchase_Date <= E.Send_Date
AND E.Send_Date < DateAdd(day, 30, C.Purchase_Date)
) THEN 1 ELSE 0 END
FROM
Customer C
WHERE
C.PurchaseDate IS NOT NULL
;
请原谅我不知道在您的 DBMS 中将日期添加 30 天的正确语法——我相信这对您来说是一个简单的解决方法。
然后您可以简单地按 PurchasedWithin30DaysOfEmailedCoupon
值分组并得到您的计数。
举个例子:我想看看我的营销工作对我想在商店里销售的产品的效果如何。例如,我想知道有多少人在 2014 年 12 月 1 日的电子邮件中收到优惠券后一个月内购买了我的产品,相比之下有多少人在同一时间段内购买了我的产品而从未收到过优惠券优惠券。 这是我的客户示例 table:
CUSTOMER_NUMBER PURCHASE_DATE
--------------- -------------
1 2014-12-02
2 2014-12-05
3 2014-12-05
4 2014-12-10
5 2014-12-21
这是我的电子邮件示例 table
CUSTOMER_NUMBER EMAIL_ADDR SEND_DATE
--------------- ------------ ----------
1 john@abc.com 2014-12-01
3 mary@xyz.com 2014-12-01
5 beth@def.com 2014-12-01
我很清楚如何确定谁用优惠券购买了产品:我在两个 table 上使用内部联接。但是为了确定谁购买了产品,即使他们出于某种原因没有优惠券(他们没有电子邮件,他们是对照组的一部分,等等),我 think 我需要用left join得到一个结果集,然后从我的第一个结果集中减去inner join的结果。 las,这就是我被困的地方。在上面的示例中,客户 2 和 5 购买了产品,即使他们从未收到过优惠券,但我不知道如何为 return 该数据编写查询。 我正在使用 IBM 的 Netezza 数据库。谢谢!!
使用 Left Outer Join
和 NULL
检查
SELECT C.*
FROM customer C
LEFT OUTER JOIN email e
ON C.customer_Number = E.customer_Number
WHERE E.customer_Number IS NULL
或使用Not Exists
SELECT *
FROM customer C
WHERE NOT EXISTS (SELECT 1
FROM email e
WHERE c.customer_number = e.customer_number)
select from customers c left outer join email e
on c.customer_number = e.customer_number
where e.customer_number is null
or C.purchase_date < e.send_date
SELECT
C.*,
PurchasedWithin30DaysOfEmailedCoupon =
CASE WHEN EXISTS (
SELECT *
FROM
Email E
WHERE
C.CustomerID = E.CustomerID
AND C.Purchase_Date <= E.Send_Date
AND E.Send_Date < DateAdd(day, 30, C.Purchase_Date)
) THEN 1 ELSE 0 END
FROM
Customer C
WHERE
C.PurchaseDate IS NOT NULL
;
请原谅我不知道在您的 DBMS 中将日期添加 30 天的正确语法——我相信这对您来说是一个简单的解决方法。
然后您可以简单地按 PurchasedWithin30DaysOfEmailedCoupon
值分组并得到您的计数。