TSQL - Как оптимизировать запрос? - PullRequest
1 голос
/ 24 ноября 2011

У меня есть таблица с новостями

News
-------
NewsId
NewsText
CREATED_DATE 

Мне нужно получать новости, начиная с указанной даты до неизвестной даты, но результат должен содержать новости за 5 дней.

Например:

  • если у меня есть новости, связанные с этими датами: 29, 28, 27, 5, 4, 3-го и с датой начала, указанной 29, мне нужно получить новости, где дата создания между 29 и 4.

Я не знаю, как получить низкую дату (4-е) в этом случае без грубой силы:

declare @highDate date = '2011-09-20';
declare @rows int = 0;
declare @lowDate date = @highDate;
declare @i int = 0;

--Querying while rows count != 5
WHILE (@rows != 5)
BEGIN

    if (@i = 60) 
        break;

    set @i = @i + 1;
    set @lowDate = (select DATEADD(day, -1, @lowDate));

    set @rows = (select COUNT(*) from
        (SELECT DAY(CAST(CREATED_DATE AS date)) as c1
        FROM .[dbo].[NEWS]
        and CREATED_DATE > @lowDate
        and CREATED_DATE < @highDate
        group by DAY(CAST(CREATED_DATE AS date))) as rowsCount);
END

--then return news between to known dates
SELECT *
FROM [dbo].[NEWS]
and CREATED_DATE > @lowDate
and CREATED_DATE < @highDate
order by CREATED_DATE desc

Я думаю, в этом алгоритме слишком много запросовпротив БД, и я бы хотел избавиться от 60-дневного ограничения

Ответы [ 2 ]

3 голосов
/ 24 ноября 2011
declare @highDate date = '2011-09-20'

select * from (
    select *,
           dense_rank() over (order by cast(created_date as date) desc) rnk 
    from News
    where CREATED_DATE <= @highDate
) as t
where t.rnk <= 5
2 голосов
/ 24 ноября 2011

Это может помочь вам.

declare @HighDate date = '2011-11-29'
declare @LowDate date

select @LowDate = min(N3.created_date)
from (
      select top(5) N2.created_date
      from (
            select distinct cast(N1.created_date as date) as created_date
            from news as N1
            where cast(N1.created_date as date) <= @HighDate
           ) as N2
      order by 1 desc
     ) as N3  

Или вы можете использовать density_rank

select @LowDate = N.created_date
from (
      select created_date,
             dense_rank() over(order by cast(created_date as date) desc) as rn
      from News 
      where cast(created_date as date) <= @HighDate 
     ) as N
where N.rn = 5     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...