如何在有条件的情况下使用LEAD功能?

时间:2018-12-20 22:10:51

标签: sql sql-server tsql lead

我正在使用查询来拉回一个客户在多天内购买商品的实例。我有兴趣仅退回客户在不同日期购买同一商品的行。

我的查询如下:

FROM (
   SELECT *,ROW_NUMBER() OVER(Partition by ordernumber,onlydate ORDER BY ordernumber  ) as ROW_Number2 
   FROM 
          (
          SELECT
                 Firstname
                 ,lastname
                 ,customerid
                 ,orderdate
                 ,ordernumber
                 ,producttype
                 ,
                     convert(date, orderdate) as onlydate,
             convert(time (0), orderdate)as onlytime
                 FROM sales a (nolock) 
                 JOIN product p(nolock)
                 ON a.customerid = p.customerid
                 WHERE orderdate BETWEEN '07/01/2018' AND '09/01/2018'

         )                   
          )as A
                       ) AS B
                       WHERE B.ROW_Number2=1 

并撤回了客户在不同日期购买商品的实例,但有时它会表明客户正在购买不同的商品。我想我需要在产品类型上使用带参数的LEAD函数,但不确定如何将其插入此查询中。

我们将不胜感激!

示例数据:

firstname    lastname     customerid   b.department  orderdate   producttype 
---------    ---------    ---------     ---------    ---------    ---------
 alice        johnson       1            athletic      12/7/17     shoes
 alice        johnson       1            athletic      12/8/18     headband
 john         parker        2            toiletries    12/9/18     cleaning
 john         parker        2            toiletries    12/10/18    personal
 john         parker        2            toiletries    12/10/18    cleaning

所需数据:

 firstname    lastname     customerid   b.department  orderdate  producttype 
---------    ---------    ---------     ---------    ---------    ---------
 john         parker        2            toiletries    12/9/18     cleaning
 john         parker        2            toiletries    12/10/18    cleaning

希望只显示约翰进行清洁的实例

5 个答案:

答案 0 :(得分:0)

嗯。 。 。

select t.*
from (select t.*,
             lag(orderdate) over (partition by customerid, department, producttype order by orderdate) as prev_orderdate,
             lead(orderdate) over (partition by customerid, department, producttype order by orderdate) as lead_orderdate
      from t
     ) t
where orderdate = dateadd(day, 1, prev_orderdate) or
      orderdate = dateadd(day, -1, next_orderdate) ;

这确实假设同一天没有多次购买,尽管可以用更多的逻辑来处理。

答案 1 :(得分:0)

WITH cte AS
 ( -- your base query
   SELECT 
        Firstname
        ,lastname
        ,customerid
        ,ordernumber
        ,department
        ,producttype
        ,convert(DATE, orderdate) AS onlydate
        ,convert(time (0), orderdate)as onlytime
   FROM sales a (nolock) 
   JOIN Product p(nolock)
   ON a.customerid = p.customerid
   WHERE orderdate BETWEEN '07/01/2018' AND '09/01/2018'
 )
,MinMaxDate AS
 ( -- adding MIN/MAX
   SELECT *
      ,MIN(onlydate) Over (PARTITION BY customerid, producttype) AS MinDate
      ,MAX(onlydate) Over (PARTITION BY customerid, producttype) AS MaxDate
   FROM UniqueDates
 )
SELECT * 
FROM TypeCount
WHERE MinDate <> MaxDate -- same product purchased on at least two days

答案 2 :(得分:0)

示例数据:

DECLARE @Data TABLE (firstname NVARCHAR(255), lastname NVARCHAR(255), customerid INT, [b.department] NVARCHAR(255), orderdate DATE, producttype NVARCHAR(255));
INSERT INTO @Data (firstname,lastname,customerid,[b.department],orderdate,producttype) VALUES 
     ('alice','johnson',1,'athletic','2017-07-12','shoes')
    ,('alice','johnson',1,'athletic','2018-08-12','headband')
    ,('john','parker',2,'toiletries','2018-09-12','cleaning')
    ,('john','parker',2,'toiletries','2018-10-12','personal')
    ,('john','parker',2,'toiletries','2018-10-12','cleaning')
;

查询:

SELECT a.*
FROM (SELECT COUNT(*)OVER(PARTITION BY d.customerid,d.producttype) AS [CountSameThingsDifferentDays],d.* FROM @Data d) a
WHERE a.CountSameThingsDifferentDays > 1
;

答案 3 :(得分:0)

也许我缺少了一些东西,但是我看不到需要Windowed函数。为什么不只使用EXISTS或CROSS APPLY:

-- prep data
SELECT * 
into #t
FROM (values 
    ('alice' ,    'johnson',       1        ,'athletic',   '12/7/17' ,   'shoes'      ),
    ('alice' ,    'johnson',       1        ,'athletic',   '12/8/18' ,   'headband'),
    ('john'  ,    'parker' ,       2        ,'toiletries', '12/9/18' ,   'cleaning'),
    ('john'  ,    'parker' ,       2        ,'toiletries', '12/10/18',   'personal'),
    ('john'  ,    'parker' ,       2        ,'toiletries', '12/10/18',   'cleaning')
)t(firstname    ,lastname     ,customerid   ,department  ,orderdate   ,producttype )


-- output using EXISTS
SELECT 
     t.firstname    
    ,t.lastname     
    ,t.customerid   
    ,t.department  
    ,t.orderdate   
    ,t.producttype 
FROM #t t
where exists (
    SELECT * 
    FROM #t it
    where 
        it.customerid = t.customerid
    and it.producttype = t.producttype
    and it.orderdate <> t.orderdate
)


-- output using a CROSS APPLY
SELECT 
     t.firstname    
    ,t.lastname     
    ,t.customerid   
    ,t.department  
    ,t.orderdate   
    ,t.producttype 
FROM #t t
cross apply (
    SELECT *
    FROM #t it 
    where 
        it.customerid = t.customerid
    and it.producttype = t.producttype
    and it.orderdate <> t.orderdate
) ct

答案 4 :(得分:0)

根据您的描述,您为我们提供了一张桌子,在原始表格中,您有两个桌子。我不清楚您的逻辑。请向我们展示如何处理原始数据。

根据我的理解,您可能不会使用lead()来获取您的要求,而只会添加一些条件。

描述更多吗?

HttpClientHandler

最好的问候

瑞秋