[英]Sql query to find the retailers who bought new product which he had not bought before
Requirement: I got 2 sets of data. 要求:我有2套数据。 Data set 1: All The retailers who purchased different items in the 3 weeks Data set 2: All The retailers who purchased different items in the 12 weeks
数据集1:全部在3周内购买了不同商品的零售商数据集2:全部在12周内购买了不同商品的零售商
I would like to pick the retailers from set 1 who bought a new product which he has not bought in the 12 weeks window. 我想从第一组中挑选零售商,他们购买了他在12周内没有购买的新产品。
I have developed the following code which is not yielding required results. 我开发了以下代码,但未产生所需的结果。 Please help
请帮忙
SELECT RC.RETAILER_CD,
RC.INV_NO,
RC.DOC_DT,
SUM (RC.SLS_ACT)
FROM RANGE_CREATION RC, ACTIVITY_TXN AV
WHERE RC.DOC_DT > ACTIVITY_START_DT
AND RC.DOC_DT <= ACTIVITY_CLOSURE_DT + 14
AND RC.RETAILER_CD = AV.CHANNEL_NAME
AND AV.TYPE = 'Range Expansion'
AND EXISTS
(SELECT RC1.RETAILER_CD, RC1.INV_NO, RC1.DOC_DT
FROM RANGE_CREATION RC1, ACTIVITY_TXN AV1
WHERE RC1.RETAILER_CD = RC.RETAILER_CD
AND RC1.RETAILER_CD = AV1.CHANNEL_NAME
AND RC1.DOC_DT > AV1.ACTIVITY_START_DT - 90
AND DOC_DT < ACTIVITY_START_DT
--AND RC1.INV_NO <> RC.INV_NO
AND RC1.ITM_CD <> RC.ITM_CD
AND AV1.TYPE = 'Range Expansion')
GROUP BY RC.RETAILER_CD, RC.INV_NO, RC.DOC_DT
HAVING SUM (RC.SLS_ACT) > 50
ORDER BY RC.RETAILER_CD, RC.INV_NO, RC.DOC_DT;
Data Set 1: 数据集1:
RETAILER_CD INV_NO DOC_DT SLS_ACT ITM_CD
R1 1 1/4/2018 10 P1
R1 1 1/4/2018 10 P2
R1 2 31/3/2018 10 P1
Data Set 2: 数据集2:
RETAILER_CD INV_NO DOC_DT SLS_ACT ITM_CD
R1 9 1/2/2018 10 P1
R1 10 2/2/2018 11 P1
R1 11 29/1/2018 12 P3
R1 12 30/1/2018 13 P4
R1 13 31/1/2018 14 P5
Result: 结果:
RETAILER_CD INV_NO DOC_DT SLS_ACT ITM_CD
R1 1 1/4/2018 10 P1
R1 1 1/4/2018 10 P2
As the INV_NO 1 from Data Set-1 has got ITM_CD P2 which the retailer hasn't bought in the 90 days period, I want to pick this invoice details. 由于数据集1的INV_NO 1拥有ITM_CD P2,零售商在90天内没有购买,因此我想选择此发票详细信息。
I tried to build it step-by-step for a better understanding: 为了更好地理解,我尝试逐步构建它:
Find the item, which is not found in dataset2 查找在dataset2中找不到的项目
select dataset1.itm_cd, dataset1.inv_no, dataset2.inv_no from
(
select 'R1' as Retailer_cd, 1 as inv_no, 10 as sls_act, 'P1' as itm_cd from dual union all
select 'R1' as Retailer_cd, 1 as inv_no, 10 as sls_act, 'P2' as itm_cd from dual union all
select 'R1' as Retailer_cd, 2 as inv_no, 10 as sls_act, 'P1' as itm_cd from dual
) dataset1, -- faketable1
(
select 'R1' as Retailer_cd, 9 as inv_no, 10 as sls_act, 'P1' as itm_cd from dual union all
select 'R1' as Retailer_cd, 10 as inv_no, 11 as sls_act, 'P1' as itm_cd from dual union all
select 'R1' as Retailer_cd, 11 as inv_no, 12 as sls_act, 'P3' as itm_cd from dual union all
select 'R1' as Retailer_cd, 12 as inv_no, 13 as sls_act, 'P4' as itm_cd from dual union all
select 'R1' as Retailer_cd, 13 as inv_no, 14 as sls_act, 'P5' as itm_cd from dual
) dataset2 -- faketable2
where 1=1
AND dataset1.itm_cd = dataset2.itm_cd (+) -- Left join -> when right table not found, row is shown anyway
AND dataset2.itm_cd is null -- only rows from dataset1 when no row in dataset2
;
Here a modern Left-join without the fake-tables for better overview 这里没有假表的现代左联接更好地概述了
SELECT dataset1.itm_cd, dataset1.inv_no, dataset2.inv_no
FROM dataset1
LEFT JOIN dataset2
ON dataset1.itm_cd = dataset2.itm_cd AND dataset2.itm_cd IS NULL
WHERE 1=1; -- no where-condition needed
Find the complete order from dataset1 to the selected item. 查找从数据集1到所选项目的完整订单。
Shorten the select to the needed values 缩短选择到所需的值
SELECT dataset1.inv_no
FROM dataset1
LEFT JOIN dataset2
ON dataset1.itm_cd = dataset2.itm_cd AND dataset2.itm_cd IS NULL;
Insert invoice-nos as table: 在表格中插入发票编号:
SELECT r.*
FROM dataset1 r, -- this will be out output
(SELECT distinct dataset1.inv_no -- added a distinct -> if two items in one invoice aren't bought in 90 days the inv_no will only be shown once.
FROM dataset1, dataset2
WHERE 1 = 1
AND dataset1.itm_cd = dataset2.itm_cd(+)
AND dataset2.itm_cd IS NULL) selectedItems -- this is the list of inv_nos
WHERE selectedItems.INV_NO = dataset1.inv_no
The original request "get retailers that bought an item in set1 they didn't buy in set2" is easy peasy: 最初的要求“让零售商在set1中购买了他们在set2中没有购买的商品”很容易:
select distinct retailer_cd
from set1
where (retailer_cd, itm_cd) not in (select retailer_cd, itm_cd from set2);
But now you have added expected results and want the complete invoices where such purchases occur, instead of merely listing the retailers. 但是,现在您已经增加了预期的结果,并希望有发生此类购买的完整发票,而不仅仅是列出零售商。 One way is to get the purchase first and then get the whole invoice in the next step with another
IN
clause: 一种方法是先获得购买,然后在下一步使用另一个
IN
子句获得整个发票:
select *
from set1
where (retailer_cd, inv_no) in
(
select retailer_cd, inv_no
from set1
where (retailer_cd, itm_cd) not in (select retailer_cd, itm_cd from set2)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.