2015-08-12 4 views
2

Итак, у меня есть таблица, в которой сделан запрос журнала. таблица выглядит следующим образом:sql самые последние две записи, отфильтрованные по дате

Id SiteId StartedAt    FinishedAt    Url 
1 2926 2015-08-10 14:53:00.230 2015-08-10 14:53:02.890 https://site1.com/Index.aspx 
2 2928 2015-08-10 14:52:57.190 2015-08-10 14:53:33.107 https://site2.com/Admin/Index.aspx 
3 2926 2015-08-10 14:53:02.897 2015-08-10 14:53:25.177 https://site1.com 
4 2926 2015-08-10 14:53:02.897 2015-08-10 14:53:48.647 https://site2.com?ID=1 
5 2926 2015-08-10 14:53:02.900 2015-08-10 14:53:48.947 https://site1.com/Tab?id=1 
6 2926 2015-08-10 14:53:02.900 2015-08-10 14:53:48.377 https://site2.com/5 

Мне нужно отобразить этот запрос в Последнего запроса и предыдущего запросом способа. См. Изображение ниже.

enter image description here

Так что я пытаюсь выбрать два самых последних запрос, сделанный для любого отдельного URL, и я могу получить эту работу. См.: Query most recent TWO entries per widget.

Однако этот список, который я использую для отображения запроса, имеет сборщик дат. Таким образом, пользователь может выбрать ответ 8/12/2015, и это будет выбор всего Last Request, который начался в этот день, и каждый из этих запросов затем показывает предыдущий запрос, который может не обязательно попадать на выбранный день, и разница между ними.

Одна строка вышеуказанной разметки будет равна двум строкам моего SQL-вывода. Поэтому для каждого уникального URL я получаю 2 строки. Представляем последний запрос и тот, который прямо перед ним.

Так вот, где я в настоящее время:

SELECT [Id], [FK_SiteId] as SiteId, [StartedAt],[FinishedAt],[Url] 
FROM SiteWarmupMetrics sw 
WHERE (Select Count(*) From SiteWarmupMetrics s 
     Where sw.Url = s.Url 
     AND s.StartedAt > sw.StartedAt) < 2 
     AND SUBSTRING(Url, CHARINDEX ('/', Url, 9), 500) = '/Index.aspx'       
ORDER BY sw.Url, sw.StartedAt 

Теперь я попытался добавить AND CONVERT(DATE, s.StartedAt) = '2015-08-10' но не совсем работает. Я чувствую, что я почти что-то пропустил.

Так вот результат я пытаюсь получить, но с запросом, который принимает в дате:

Id SiteId StartedAt    FinishedAt    Url 
20 2928 2015-08-10 16:12:39.430 2015-08-10 16:13:14.157 https://site1.com/Index.aspx 
38 2928 2015-08-12 11:22:46.593 2015-08-12 11:23:16.183 https://site1.com/Index.aspx 
19 2926 2015-08-10 16:12:39.430 2015-08-10 16:12:45.207 https://site2.com/Index.aspx 
37 2926 2015-08-12 11:22:46.587 2015-08-12 11:22:52.030 https://site2.com/Index.aspx 
+0

Не могли бы вы разместить http://sqlfiddle.com/ свою структуру и данные таблицы? – Hackerman

+0

Какую версию SQL Server вы используете? В последних версиях есть «оконные» функции, которые позволяют вам легко получить доступ к предыдущей строке, что может оказаться полезным ... пока вы можете гарантировать выполнение только SQL2014 или более поздних версий. – pmbAustin

+0

К сожалению, я запускаю его на SQL 2008 – Adam

ответ

1

Tab был закрыт, необходимо разделить по URL, а не SiteID. Кроме того, объединение в выборе не требуется, вместо этого выберите строки с ROW_NUMBER() < = 2, поэтому он возьмет первые два результата от cte.

DECLARE @FromDate DATETIME = '2015-08-10' 
;WITH cte AS (
    SELECT [Id], [FK_SiteId] as SiteId, [StartedAt],[FinishedAt],[Url], 
    ROW_NUMBER() OVER (PARTITION BY Url ORDER BY StartedAt DESC) AS rn 
    FROM SiteWarmupMetrics 
    WHERE CONVERT(DATE, StartedAt) <= CONVERT(Date, @FromDate) 
) 
SELECT [Id], SiteId, [StartedAt],[FinishedAt],[Url] 
FROM cte WHERE cte.Rn <= 2 
0

SQL Server 2008 не имеет функции LAG, но у него есть ROW_NUMBER() ,

Чтобы получить результаты в последнем примере кода, и предполагая, что вы передаете выбор выбора даты пользователя в качестве параметра называется @FromDate это следует сделать трюк:

WITH cte AS (
    SELECT [Id], [FK_SiteId] as SiteId, [StartedAt],[FinishedAt],[Url] 
    ROW_NUMBER() OVER (PARTITION BY FK_SiteId ORDER BY StartedAt DESC) AS rn 
    FROM SiteWarmupMetrics 
    WHERE StartedAt >= @FromDate 
) 
SELECT [Id], SiteId, [StartedAt],[FinishedAt],[Url] 
FROM cte 
WHERE rn=1 
UNION ALL 
SELECT s1.[Id], s1.FK_SiteId AS SiteId, s1.[StartedAt],s1.[FinishedAt],s1.[Url] 
FROM cte 
LEFT OUTER JOIN SiteWarmupMetrics s1 
    ON cte.[Id]=(
    SELECT TOP 1 [Id] 
    FROM SiteWarmupMetrics s2 
    WHERE cte.SiteId=s2.FK_SiteId 
    AND s2.StartedAt < cte.StartedAt 
    ORDER BY s2.StartedAt DESC 
) 
WHERE cte.rn=1 
ORDER BY SiteId, StartedAt 

EDIT: Моя первая попытка была путает нужно получить первую строку ПОСЛЕ параметра FromDate, но затем строку ДО того, которая может быть до или после параметра. Мой текущий запрос также должен решить.

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