繁体   English   中英

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

[英]Sql query to find the retailers who bought new product which he had not bought before

要求:我有2套数据。 数据集1:全部在3周内购买了不同商品的零售商数据集2:全部在12周内购买了不同商品的零售商

我想从第一组中挑选零售商,他们购买了他在12周内没有购买的新产品。

我开发了以下代码,但未产生所需的结果。 请帮忙

 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;

数据集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

数据集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

结果:

RETAILER_CD INV_NO  DOC_DT  SLS_ACT ITM_CD
R1            1    1/4/2018   10     P1
R1            1    1/4/2018   10     P2

由于数据集1的INV_NO 1拥有ITM_CD P2,零售商在90天内没有购买,因此我想选择此发票详细信息。

为了更好地理解,我尝试逐步构建它:

第一步

查找在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
;

现代左联接

这里没有假表的现代左联接更好地概述了

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

第二步

查找从数据集1到所选项目的完整订单。

* 2a缩短选择

缩短选择到所需的值

SELECT dataset1.inv_no
  FROM dataset1
       LEFT JOIN dataset2
           ON dataset1.itm_cd = dataset2.itm_cd AND dataset2.itm_cd IS NULL;

* 2b

在表格中插入发票编号:

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

最初的要求“让零售商在set1中购买了他们在set2中没有购买的商品”很容易:

select distinct retailer_cd
from set1
where (retailer_cd, itm_cd) not in (select retailer_cd, itm_cd from set2);

但是,现在您已经增加了预期的结果,并希望有发生此类购买的完整发票,而不仅仅是列出零售商。 一种方法是先获得购买,然后在下一步使用另一个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