2013-08-15 2 views
1

나는 다음 코드를 가지고 있지만 @test 테이블과 그 기본 where 절을 두 번 이상 참조하지 않는 것을 선호한다. ROWCOUNT로 리팩토링을 시도했지만 해결할 수는 없다.이 SQL을 리팩터링 할 수 있습니까?

declare @test2 table(ID int, ExpiryDate datetime, userid int, siteid int, Status int) 
insert into @test2 (ID, ExpiryDate, userid, siteid, Status) 
--not expired/status=40 and not status=40 entries 
select 1, '2013-08-16', 1, 1, 40 
union 
select 2, '2013-08-16', 1, 1, 10 
union 
--not expired/status=40 and status=40 entries 
select 3, '2013-08-16', 2, 2, 40 
union 
select 4, '2013-08-16', 2, 2, 40 
union 
--expired/status=40 and not status=40 entries 
select 5, '2013-08-13', 3, 3, 40 
union 
select 6, '2013-08-16', 3, 3, 10 
union 
--expired/status=40 and status=40 entries 
select 7, '2013-08-13', 4, 4, 40 
union 
select 8, '2013-08-16', 4, 4, 40 
union 
--not expired/status=40 single entry 
select 9, '2013-08-16', 5, 5, 40 
union 
--expired/status=40 single entry 
select 10, '2013-08-13', 6, 6, 40 


/* scenarios: 
not expired/status=40 and not status=40 entries - sees both  - userid = 1 
not expired/status=40 and status=40 entries  - sees both  - userid = 2 
expired/status=40 and not status=40 entries  - sees both  - userid = 3 
expired/status=40 and status=40 entries   - sees single - userid = 4 
not expired/status=40 single entry     - sees single - userid = 5 
expired/status=40 single entry      - sees single - userid = 6 
*/ 

내가이 리팩토링 할 수 있습니다 모르겠어요 :

select * 
from @test2 
where userid = @userid 
    and (
     ExpiryDate > getdate() 
      or 
     not exists(select * from @test2 
         where userid = @userid 
         and ExpiryDate > Getdate() 
         and Status = 40) 
     ) 

내가 테스트를 위해 사용하고 데이터입니다. 이 아이디어를 향상시키는 방법에 대한 아이디어가있는 분은 정말로 감사하겠습니다.

감사

+0

초기 데이터를 예상 ... – MrSimpleMind

답변

1

시도하십시오 도움이 될 것입니다 전에 쿼리 실행 후 데이터를

;with cte as (
    select ID, ExpiryDate, userid, siteid, Status, 
     notExp = case when ExpiryDate > getdate() then 1 end, 
     notExp_st40 = sum(case when ExpiryDate > getdate() and Status = 40 then 1 end) over() 
    from @test2 
    where userid = @userid 
) 
select ID, ExpiryDate, userid, siteid, Status 
from cte 
where notExp=1 or notExp_st40 is NULL 
+0

이 마법처럼 일했다 - 당신에게 – blugeblarbla

+0

무엇입니다 감사합니다 합계 이후의()의 중요성? – blugeblarbla

+0

'over()'합계를 사용하면 행의 하위 집합에 대한 합계를 계산할 수 있습니다. [여기 (예제 섹션의 예제 B) 참조] (http://technet.microsoft.com/ko-kr/library/ms189461.aspx)'over' 절 뒤에 괄호 안에있는 것은 _all_ 행에 대한 합계가 계산된다는 것을 의미합니다. 따라서이 경우 행을이 열로 필터링 할 수 있도록'group by '을 사용할 필요없이 합계가 계산되어 모든 행에 추가 열로 첨부됩니다. –

관련 문제