2015-12-28 97 views
1

我正在使用SQL語法的數據庫系統上工作。但是我無法在下面的代碼中使用交叉應用。有沒有辦法重寫這個沒有適用?將SQL Server查詢更改爲純ANSI SQL查詢

declare @rsBuildDetails table(dt datetime, build varchar(255), val varchar(255)); 

insert into @rsBuildDetails (dt, build, val) 
values ('20100101', '1', 'pass') 
     ,('20100102', '2', 'fail') 
     ,('20100103', '3', 'pass') 
     ,('20100104', '4', 'fail') 
     ,('20100105', '5', 'fail') 
     ,('20100106', '6', 'fail') 
     ,('20100107', '7', 'pass') 
     ,('20100108', '8', 'pass') 
     ,('20100109', '9', 'pass') 
     ,('20100110', '10', 'fail'); 

with passed as 
(
    select * 
    from @rsBuildDetails 
    where val='pass' 
) 
select distinct 
    preFail.dt AS FailedDt, 
    postFail.dt AS SecondFailedDt 
from 
    passed 
cross apply 
    (select top 1 
     pre.* 
    from 
     @rsBuildDetails as pre 
    where 
     pre.dt < passed.dt 
     and pre.val = 'fail' 
    order by 
     pre.dt desc) as preFail 
cross apply 
    (select top 1 
     post.* 
    from 
     @rsBuildDetails as post 
    where 
     post.dt > passed.dt 
     and post.val = 'fail' 
    order by 
     post.dt asc) as postFail 
+0

難道你真的想要一個純粹的ANSI SQL查詢,或你想要一個特定的RDBMS? –

+0

@Tim,Shnugo能夠回答我的問題。謝謝 – jyim89

回答

2

你可以嘗試轉移CTE和所有適用於內聯子選擇:

declare @rsBuildDetails table(dt datetime, build varchar(255), val varchar(255)); 

insert into @rsBuildDetails (dt, build, val) values 
('20100101', '1', 'pass') 
,('20100102', '2', 'fail') 
,('20100103', '3', 'pass') 
,('20100104', '4', 'fail') 
,('20100105', '5', 'fail') 
,('20100106', '6', 'fail') 
,('20100107', '7', 'pass') 
,('20100108', '8', 'pass') 
,('20100109', '9', 'pass') 
,('20100110', '10', 'fail'); 

select * 
from 
(
    select distinct 
      (
      select top 1 pre.Dt 
      from @rsBuildDetails as pre 
      where pre.dt<passed.dt 
       and pre.val='fail' 
      order by pre.dt desc 
      ) as FailedDt 
     ,(
      select top 1 post.Dt 
      from @rsBuildDetails as post 
      where post.dt>passed.dt 
       and post.val='fail' 
      order by post.dt asc 
     ) AS SecondFailedDt 
    from 
    (
     select * 
     from @rsBuildDetails 
     where val='pass' 
    ) AS passed 
) AS tbl 
where tbl.FailedDt IS NOT NULL 
    AND tbl.SecondFailedDt IS NOT NULL 
+0

這是完美的。正是我在找什麼。我會盡快接受答案。 – jyim89

+0

@ jyim89謝謝,請閱讀[this:someone-answers](http://stackoverflow.com/help/someone-answers)。我訪問了你的個人資料,發現你很少接受答案......這對於向其他用戶展示這個問題已經解決(如果是......)很重要,並且它會給答覆者一些信譽點。順便說一句:接受和投票是兩個獨立的步驟。所有回答者都非常感激,如果你們兩個都這樣做,thx! – Shnugo