简体   繁体   English

SQL查询以查找购买了他之前从未购买过的新产品的零售商

[英]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: 为了更好地理解,我尝试逐步构建它:

1st step 第一步

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
;

Modern Left-Join 现代左联接

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

2nd step 第二步

Find the complete order from dataset1 to the selected item. 查找从数据集1到所选项目的完整订单。

* 2a Shorten the select * 2a缩短选择

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;

* 2b * 2b

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM