2017-08-24 16 views
4

我身边有一个网站,该网站有不同的店的部分,但是当用户在年底检查出来,我们只知道一些数据的记录是通过寻找他们最什么铺段近期部分打SQL窗口坚持在给定的条件

例如,如果我有一个看起来像

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 

我想坚持他们去(其中存在最后存储数据仅供当他们在一买一节的网页(即页面名称以“buy”开头)

输出我期待的是:

session, hit_number, 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 
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 
a,5,home_page,null 
+0

呃......你可以这样做。我都是进行分析,但应该诚实地不会在SQL中捕获这些数据。您将遇到影响未来扩展的数据库。您应该使用实时日志监控应用程序。我全心全意为正确的工作提供正确的工具。我不认为我可以给出链接,但我对Splunk有所偏爱。您可以通过这种方式获得更多的数据分析。就像比较页面浏览到销售..计划的报告和实时仪表板...等... –

+0

@SteveKline这是一个关闭,我不需要使用splunk或监视任何东西。我只是做一次性分析 – shecode

+0

你在使用什么供应商,例如SQL服务器,MySQL,Oracle,Postgres等......? – ttallierchio

回答

2

如果你的模式是这样的:

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的评论认为,这似乎不是正确的方法。

3

我在SQL Server但查询得到的结果在多数供应商合作,这样做。其背后的逻辑是,检查时page列包含'buy'然后拿到min值即上面对网页名称中包含'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 
1

据我了解,直到另一个页面被访问的“上次访问商店页面”应persistet或会话结束。我是在后端进行这种操作的朋友。围绕add操作的触发器或存储过程应该能够做到。特别是添加触发器可能会起作用。但是你可以使用,是理想的选择至极很大程度上取决于你所使用的DBMS(不是所有有两个选项和性能可大不相同过同样的支持)。

就我个人而言,我会在会话中坚持“上次访问过的商店”,并将其添加到所有插入。我认为在显示表2个触发器可以这样做:

,试图更新会话方
  • 一个触发“最后访问的网页”条目每次的东西被添加到该表。
  • 而且还有一个触发器或存储过程用于将会话的“last visited页面”从会话传输到此表。

INSTEAD OF触发器,你当然也可以使用所有包装此存储过程,但恕我直言触发器是在这种情况下,清洁剂,因为它不依赖于如何添加的数据。正常会话清理代码也会处理清理临时数据。而会话的默认值可以是“null”。您应该考虑在两个触发器代码中都没有会话(无论出于何种原因)的罕见事件。 当然这只是为了将来添加它。它不会追溯适用于现有的表格。

如果您希望它适用于所有现有和将来的数据,视图上的计算列将是我拥有的最佳创意。至少DBMS可以对这些缓存进行适当的缓存。但是它又取决于DBMS,以及它是否支持类似计算列的视图。