2017-10-26 4 views
1

ここでは、同じCIDに対してofferdate nullとprevoius offer dateがnullでないcustomerIDの結果が必要です。nullとprevレコードでないレコードをSQLで検索する

現在の結果:

  CID    orderDate   offerdate1 
      1    2015-08-11   2014-08-10 
      1    2015-08-12   2014-08-11 
      1    2015-08-12   NULL     
      2    2016-08-13   2015-08-11 
      2    2016-08-13   2015-08-12 
      3    2016-08-13   NULL 
      4    2016-01-12   2016-01-12 
      4    2016-02-12   Null 

期待される結果:

  CID    orderDate   offerdate1 
      1    2015-08-12   2014-08-11 
      1    2015-08-12   NULL 
      4    2016-01-12   2016-01-12 
      4    2016-02-12   Null 

など。 CID = '1'の場合 最近の注文日は2015-08-12で、提供日はNULLです。 しかし、同じCIDはprevoiusでの引出日を持っています。orderdate.i.e.'2014-08-11 ' 私はofferdateがnullで、以前のorderdateでofferdateをシェービングしているレコードのみを必要とします。

+0

まだ試しましたか?私はこのサイトが仕事をするためのものだとは思わない。あなたが試したことと直面している問題は何かを教えてください。 –

答えて

1

getDate()を置き換えることができ、後であなたが使用することができます。

DECLARE @DataSource TABLE 
(
    [CID] INT 
    ,[orderDate] DATE 
    ,[offerdate1] DATE 
); 

INSERT INTO @DataSource ([CID], [orderDate], [offerdate1]) 
VALUES (1, '2015-08-11', '2014-08-10') 
     ,(1, '2015-08-12', '2014-08-11') 
     ,(1, '2015-08-12', NULL) 
     ,(2, '2016-08-13', '2015-08-11') 
     ,(2, '2016-08-13', '2015-08-12') 
     ,(3, '2016-08-13', NULL) 
     ,(4, '2016-01-12', '2016-01-12') 
     ,(4, '2016-02-12', NULL); 

WITH DataSource AS 
(
    SELECT * 
      ,ROW_NUMBER() OVER(PARTITION BY [CID] ORDER BY [orderDate], [offerdate1] DESC) AS [RowID] 
    FROM @DataSource 
), 
FinalDataSource AS 
(
    SELECT DS1.[CID] 
      ,DS1.[orderDate] 
      ,DS1.[offerdate1] 
      ,DS2.[CID] AS DS2_CID 
      ,DS2.[orderDate] AS DS2_orderDate 
      ,DS2.[offerdate1] AS DS2_offerdate1 
    FROM DataSource DS1 
    INNER JOIN DataSource DS2 
     ON DS1.[CID] = DS2.[CID] 
     AND DS1.[RowID] = DS2.[RowID] + 1 
    WHERE DS1.[offerdate1] IS NULL 
) 
SELECT [CID] 
     ,[orderDate] 
     ,[offerdate1] 
FROM FinalDataSource 
UNION ALL 
SELECT [DS2_CID] 
     ,[DS2_orderDate] 
     ,[DS2_offerdate1] 
FROM FinalDataSource; 

enter image description here

2

ウィンドウ機能を試してください。 LAG(offerdate)は、の行を検出できます。前の値はNOT NULLとなります。LEAD(offerdate), LEAD(orderdate)は、NULL行の前の行を検出します。

select t.cid, t.orderdate, t.offerdate 
from 
(
    select *, 
     lag(offerdate) over (partition by cid order by orderdate, coalesce(offerdate,getdate())) offerlag, 
     lead(offerdate) over (partition by cid order by orderdate, coalesce(offerdate,getdate())) offerlead, 
     lead(orderdate) over (partition by cid order by orderdate, coalesce(offerdate,getdate())) orderlead 
    from your_table 
) t 
where t.offerdate is null and t.offerlag is not null or -- NULL row detection 
     t.offerdate is not null and t.offerlead is null and t.orderlead is not null -- row preceding the NULL row detection 
order by cid, orderdate, coalesce(offerdate,getdate()) 

demo

私のソリューションは、今日の日付、次の何日が存在しないことを前提としています。それが真でない場合は、私の解決策ではgetdate()をデータベースの日付よりも大きい日付に置き換えてください。あなたは、データベース(なし将来の日付)で今日の日付を持っている場合たとえば、あなたはSQL Server 2008についてはdateadd(day, 1, getDate())

0

「CURRENT Result:」の値を新しいテーブルt1に挿入しました。結果は期待通りです:

select * from (
    select * from t1 where cid in 
     (select cid from t1 where offerdate1 is null group by cid) and cid not in 
     (select cid from ( 
     (select cid, min(offerdate1), max(offerdate1) from t1 having min(offerdate1) is null group by cid))) and offerdate1 is null 
    union all 
    select cid, min(orderdate), max(offerdate1) from (
     select * from t1 where cid in 
     (select cid from t1 where offerdate1 is null group by cid) and cid not in 
     (select cid from ( 
     (select cid, min(offerdate1), max(offerdate1) from t1 having min(offerdate1) is null group by cid)))) group by cid 
) order by cid, orderdate; 
0
 select b.cid, 
       b.orderDate, 
       b.offerdate1 
     from 
     (
     select cid, 
       orderDate, 
       offerdate1 
     From #temp A 
     where A.offerdate1 is null 
     and exists ( 
     select 1 from #temp B 
     where a.cid = b.cid 
     and  B.offerdate1 is not null ) 

     ) a 
     inner join #temp b 
     on a.cid = b.cid 
     where b.offerdate1 = (select max(offerdate1) from #temp C where c.cid = a.cid) 

     union all 

     select cid, 
       orderDate, 
       offerdate1 
     From #temp A 
     where A.offerdate1 is null 
     and exists ( 
     select 1 from #temp B 
     where a.cid = b.cid 
     and  B.offerdate1 is not null ) 
     order by cid,offerdate1 desc 
+0

最初のレコードに対して複数回試してみてください –

関連する問題