在给定条件下保留记录的sql窗口

在给定条件下保留记录的sql窗口,sql,windowing,Sql,Windowing,我有一些关于一个网站的数据,该网站有不同的商店部分,但当用户在最后结账时,我们只能通过查找他们最近的部分点击来知道它是什么商店部分 例如,如果我有如下数据 我想保留他们上一次去的商店(存在的地方,并且仅当他们在网页的“购买”部分时(即,页面名称以“购买”开头) 我期望的结果是: 如果您的架构如下所示: create table weblog (session varchar(10) ,hit_number int ,page varchar(30) ); INSERT INTO weblog

我有一些关于一个网站的数据,该网站有不同的商店部分,但当用户在最后结账时,我们只能通过查找他们最近的部分点击来知道它是什么商店部分

例如,如果我有如下数据

我想保留他们上一次去的商店(存在的地方,并且仅当他们在网页的“购买”部分时(即,页面名称以“购买”开头)

我期望的结果是:


如果您的架构如下所示:

create table weblog
(session varchar(10)
,hit_number int
,page varchar(30)
);

INSERT INTO weblog VALUES 
('a',1,'homepage')
,('a',2,'generic_page')
,('a',3,'shoe_store')
,('a',4,'buy_add_basket')
,('a',5,'buy_checkout')
,('b',1,'sock_store')
,('b',2,'shoe_store')
,('b',3,'buy_add_to_basket')
,('b',4,'buy_checkout')
,('c',1,'homepage')
,('c',2,'sock_store')
,('c',3,'sock_store')
,('c',4,'buy_add_to_basket')
,('c',5,'home_page')
,('c',6,'shoe_store')
,('a',5,'home_page');
然后需要一个SELECT语句,如:

SELECT "session"
, hit_number
, page
, CASE 
  WHEN page like 'buy%' THEN 
  max(CASE 
        WHEN page like '%store' THEN page 
        ELSE NULL
      END) OVER (PARTITION BY session ORDER BY hit_number)
  ELSE NULL
  END as last_store
FROM weblog;
(这是postgres 9.6,您使用的是哪个数据库?)


顺便说一句,我同意@SteveKline的评论,即这似乎不是正确的方法。

我在SQL Server中这样做了,但在大多数供应商中,获取结果的查询都是有效的。其背后的逻辑是检查
页面
列何时包含
'buy'
然后获取
最小值,即上面的值,其中t页面名称包含
'store'

创建并填充表格:

DECLARE @table TABLE
(
    session    VARCHAR(1),
    hit_number INT,
    page       VARCHAR(50)
);
INSERT INTO @table VALUES 
('a',1,'homepage'),
('a',2,'generic_page'),
('a',3,'shoe_store'),
('a',4,'buy_add_basket'),
('a',5,'buy_checkout'),
('b',1,'sock_store'),
('b',2,'shoe_store'),
('b',3,'buy_add_to_basket'),
('b',4,'buy_checkout'),
('c',1,'homepage'),
('c',2,'sock_store'),
('c',3,'sock_store'),
('c',4,'buy_add_to_basket'),
('c',5,'home_page'),
('c',6,'shoe_store'),
('a',5,'home_page');
Select*From@table
将给出以下结果:

session hit_number  page
a       1           homepage
a       2           generic_page
a       3           shoe_store
a       4           buy_add_basket
a       5           buy_checkout
b       1           sock_store
b       2           shoe_store
b       3           buy_add_to_basket
b       4           buy_checkout
c       1           homepage
c       2           sock_store
c       3           sock_store
c       4           buy_add_to_basket
c       5           home_page
c       6           shoe_store
a       5           home_page
查询:

SELECT
    session,
    hit_number,
    page,
    CASE
        WHEN page LIKE 'buy%'
        THEN MIN(CASE
                     WHEN page LIKE '%store'
                     THEN page
                     ELSE NULL
                 END) OVER(PARTITION BY session ORDER BY hit_number)
        ELSE NULL
    END AS previous_buy_page
FROM @table;
返回所需的结果:

session hit_number  page                previous_buy_page
a       1           homepage            NULL
a       2           generic_page        NULL
a       3           shoe_store          NULL
a       4           buy_add_basket      shoe_store
a       5           buy_checkout        shoe_store
a       5           home_page           NULL
b       1           sock_store          NULL
b       2           shoe_store          NULL
b       3           buy_add_to_basket   shoe_store
b       4           buy_checkout        shoe_store
c       1           homepage            NULL
c       2           sock_store          NULL
c       3           sock_store          NULL
c       4           buy_add_to_basket   sock_store
c       5           home_page           NULL
c       6           shoe_store          NULL
据我所知,“上次访问的商店页面”应该是持久的,直到访问另一个页面或会话结束。我是在后端执行此类操作的朋友。add Opartion周围的触发器或存储过程应该能够执行此操作。特别是add trigger可能会工作。但是,您可以使用哪个选项,并且理想的选项在很大程度上取决于您使用的DBMS(并非所有人对这两种选择都有同等的支持,而且表现也可能大相径庭)

就我个人而言,我会在会话中保留“last storepage visited”,并将其添加到所有插入中。我认为所示表格上的两个触发器可以实现这一点:

  • 每次向该表添加内容时,一个触发器会尝试更新会话端“上次访问的页面”条目
  • 以及一个触发器或存储过程,用于传输“最后一个 从会话到此表的“已访问页面”
当然,您也可以使用一个存储过程来包装这一切,而不是触发器,但在这种情况下,IMHO触发器更干净,因为它不依赖于数据的添加方式。正常会话清理代码还将处理临时数据的清理。会话的默认值可以是“null”您应该考虑在两个触发器代码中都没有会话(无论什么原因)的罕见情况。 当然,这只是为了将来添加它。它不会追溯到现有的表


如果你想将其应用于所有现有和未来的数据,在视图上设置一个计算列将是我最好的主意。至少DBMS可以在这些数据上进行大量的缓存。但这同样取决于DBMS,以及它是否支持类似于计算列的视图。

Eh…你可以这样做。我完全支持分析,但老实说,不应该不要在SQL中捕获这些数据。你将来会遇到影响数据库扩展的问题。你应该使用实时日志监控应用程序来实现这一点。我认为我可以为正确的工作提供正确的工具。我不认为我可以提供链接,但我倾向于Splunk。这样你可以获得更多的数据分析。比如将页面视图与sal进行比较es..scheduled reports and Real Time Dashboard…等@SteveKline这是一次性的,我不需要使用splunk来实现它或监视任何东西。我只是在做一次性分析您使用的是哪家供应商,即SQL server、MySQL、Oracle、Postgres等?
SELECT
    session,
    hit_number,
    page,
    CASE
        WHEN page LIKE 'buy%'
        THEN MIN(CASE
                     WHEN page LIKE '%store'
                     THEN page
                     ELSE NULL
                 END) OVER(PARTITION BY session ORDER BY hit_number)
        ELSE NULL
    END AS previous_buy_page
FROM @table;
session hit_number  page                previous_buy_page
a       1           homepage            NULL
a       2           generic_page        NULL
a       3           shoe_store          NULL
a       4           buy_add_basket      shoe_store
a       5           buy_checkout        shoe_store
a       5           home_page           NULL
b       1           sock_store          NULL
b       2           shoe_store          NULL
b       3           buy_add_to_basket   shoe_store
b       4           buy_checkout        shoe_store
c       1           homepage            NULL
c       2           sock_store          NULL
c       3           sock_store          NULL
c       4           buy_add_to_basket   sock_store
c       5           home_page           NULL
c       6           shoe_store          NULL