【问题标题】:sql most recent two records filtered on datesql最近的两条记录过滤日期
【发布时间】:2015-11-05 12:49:34
【问题描述】:

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

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

我需要以 Last RequestPrevious Request 的方式显示这些请求。见下图。

所以我正在尝试选择对任何单个 URL 发出的两个最新请求,我可以让它工作。见:Query most recent TWO entries per widget

但是,我用来显示请求的这个列表有一个日期选择器。因此,用户可以选择 8/12/2015,这将选择当天开始的所有 Last Request,然后每个请求都会显示 previous 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

【问题讨论】:

  • 你能发一个sqlfiddle.com你的表结构和数据吗?
  • 您使用的是什么版本的 SQL Server?最新版本具有“窗口”功能,可让您更轻松地访问前一行,这可能很有用......只要您可以保证仅在 SQL2014 或更高版本上运行。
  • 不幸的是我在 SQL 2008 上运行它
  • @ZoharPeled:这将适用于一个站点的结果,因为前 2 个站点会限制它。我需要一个查询来获取每个唯一网址的最后两个。
  • 每个唯一的 url 或每个唯一的站点 ID?我建议编辑您的问题以使其更清晰。

标签: sql sql-server date


【解决方案1】:

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 参数之后获取第一行而感到困惑,但在此之前的行可能在参数之前或之后。我当前的查询也应该解决这个问题。

【讨论】:

    【解决方案2】:

    选项卡已关闭,需要按 Url 而不是 SiteID 分区。此外,select 中的 union 不是必需的,而是选择 ROW_NUMBER()

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多