2013-08-15 5 views
1

У меня есть следующий код, но я бы предпочел не ссылаться на таблицу @test и ее базовое предложение where несколько раз, я попытался реорганизовать его с помощью ROWCOUNT, но не могу его решить.Можно ли реорганизовать этот SQL?

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

Это данные я использую для тестирования:

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 
*/ 

Я даже не уверен, что можно реорганизовать это. Любой, у кого есть идеи, как улучшить это, будет действительно оценен.

Благодаря

Джон

+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

, что значение over() после суммы? – blugeblarbla

+0

'over()' после того, как сумма позволяет вычислять сумму по подмножеству строк (см. [Здесь (пример B в разделе «Примеры»)] (http://technet.microsoft.com/en-us/library/ms189461.aspx).) Ничто в круглых скобках после предложения 'over' означает, что вычисляется сумма по _all_ rows. Таким образом, в этом случае сумма вычисляется и привязывается к каждой строке как дополнительный столбец без необходимости использования 'group by', чтобы затем строки могли быть отфильтрованы этим столбцом. –

Смежные вопросы