sql最近在日期过滤了两条记录

时间:2015-08-12 18:51:32

标签: sql sql-server date

所以我有一个记录请求的表。 表格如下:

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

因此,我尝试选择针对任何单个网址提出的两个最新请求,我可以将其工作。请参阅:Query most recent TWO entries per widget

但是,我用来显示请求的列表中有一个日期选择器。因此,用户可以选择说2015年12月12日,这将选择当天开始的所有上次请求,然后每个请求都会显示上一个请求,可能不一定落在选定的日子,以及两者之间的差异。

上述标记的一行将等同于我的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

2 个答案:

答案 0 :(得分:1)

Tab已关闭,需要Partition By Url而不是SiteID。此外,选择中的联合不是必需的,而是选择ROW_NUMBER()&lt; = 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

答案 1 :(得分: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

编辑:我的第一次尝试因需要在FromDate参数之后获取第一行,然后是BEFORE之前的那一行,可能是在参数之前或之后。我当前的查询也应该解决这个问题。