如何查询以前的行?

时间:2014-08-25 00:48:20

标签: sql sql-server

我有一个页面审核表,记录用户访问过的页面。给定一个特定的页面,我需要找到用户访问过的前一页以及访问最多的页面。

例如,FAQ Page_ID为3.我想知道是否更频繁地从First Access页面(ID 1)或主页(ID 5)访问它。

示例:

页面审核表(SQL Server)

ID  | Page_ID | User_ID
1   | 1       | 6
2   | 3       | 6
3   | 5       | 4
4   | 3       | 4
5   | 1       | 7
6   | 3       | 7
7   | 1       | 5
8   | 3       | 2        --Note: previous user is not 2
9   | 3       | 5        --Note: previous page for user 5 is 1 and not 3

寻找Page_ID = 3,我想检索:

Previous Page | Count
1             | 3
5             | 1

注意:我在这里看了一些类似的问题(比如one),但它对我解决这个问题没有帮助。

3 个答案:

答案 0 :(得分:3)

您可以使用窗口函数作为解决此问题的一种方法:

with UserPage as (
  select
    User_ID,
    Page_ID,
    row_number() over (partition by User_ID order by ID) as rn
  from
    PageAudit
)
select
  p1.Page_ID,
  count(*)
from
  UserPage p1
    inner join
  UserPage p2
    on p1.User_ID = p2.User_ID and
       p1.rn + 1 = p2.rn
where
  p2.Page_ID = 3
group by
  p1.Page_ID;

SQLFiddle Demo

如果你有SQL2012,使用lag的答案会更有效率。这个也适用于SQL2008。

作为参考,我认为其中一个滞后解决方案过于复杂,一个是错误的:

with prev as (
  select
    page_id,
    lag(page_id,1) over (partition by user_id order by id) as prev_page
  from 
    PageAudit
)
select
  prev_page,
  count(*)
from
  prev
where
  page_id = 3 and
  prev_page is not null -- people who landed on page 3 without a previous page
group by 
  prev_page

SQLFiddle Example of Lag

答案 1 :(得分:2)

select prev_page, count(*)
  from (select id,
               page_id,
               user_id,
               lag(page_id, 1) over(partition by user_id order by id) as prev_page
          from page_audit_table) x
 where page_id = 3
   and prev_page <> page_id
 group by prev_page

<强>小提琴: http://sqlfiddle.com/#!6/c0037/23/0

答案 2 :(得分:1)

您可以使用LAG功能(仅在MS SQL Server 2012 +中可用)。

使用此fiddle进行测试。

查询:

SELECT
    previous_page, count(previous_page) as count
FROM
    (SELECT
        Page_id,
        LAG(Page_ID, 1, NULL) OVER (PARTITION BY User_ID ORDER BY ID) as previous_page,
        User_ID as current_usr,
        LAG(User_ID, 1, NULL) OVER (PARTITION BY User_ID ORDER BY ID) as previous_usr
    FROM
        Page_Audit) p
WHERE
    Page_ID = 3 AND current_usr = previous_usr
GROUP BY
    previous_page
ORDER BY
    count DESC