Changing SQL Server query to pure ANSI SQL query

三世轮回 提交于 2019-12-11 12:22:17

问题


I am working on a database system that uses SQL syntax. However I am unable to use the cross apply in the code below. Is there a way to rewrite this without applies?

 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

回答1:


You might try to transfer the CTE and all applies to inlined sub-selects:

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


来源:https://stackoverflow.com/questions/34493289/changing-sql-server-query-to-pure-ansi-sql-query

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!