2008-11-25 63 views
0

我有几个表用于记录应用程序的用户活动。该表看起来是这样的(从内存伪代码,可能不是语法正确):SQL Server - 使用另一个表的第一行和最后一行更新一个表

create table activity (
    sessionid uniqueidentifier not null, 
    created smalldatetime not null default getutcdate() 
); 

create table activity_details (
    sessionid uniqueidentifier not null, 
    activity_description varchar(100) not null, 
    created smalldatetime not null default getutcdate() 
); 

我的目标是填充汇总表报告的目的,看起来是这样的:

create table activity_summary (
    sessionid uniqueidentifier not null, 
    first_activity_desc varchar(100) not null, 
    last_activity_desc varchar(100) not null 
); 

首先和最后的活动描述将按时间顺序确定。我最初的想法是更新汇总表如下所示:

truncate table activity_summary; 

insert into activity_summary (sessionid) 
select sessionid from activity; 

update table activity_summary set 
    first_activity_desc = (select top 1 activity_desc from activity_detail where sessionid = as.sessionid order by created asc), 
    last_activity_summary = (select top 1 activity_desc from activity_detail where sessionid = as.sessionid order by created desc) 
from activity_summary as; 

然而,这似乎令人难以置信的冗长和不必要的给我。我只是不确定如何缩小它。我的直觉是,我可以在插入语句中以某种方式做到这一点,但我很难过。有什么建议么?

回答

1

很可能有更有效的方式来做到这一点为好,但这是最接近原始的:

truncate table activity_summary; 

insert into activity_summary (sessionid, first_activity_desc, last_activity_summary) 
select a.sessionid 
,(select top 1 ad.activity_desc from activity_detail AS ad where ad.sessionid = a.sessionid order by ad.created asc) AS first_activity_desc 
,(select top 1 ad.activity_desc from activity_detail AS ad where ad.sessionid = a.sessionid order by ad.created desc) AS last_activity_summary 
from activity AS a; 

像这样的东西可能更有效:

truncate table activity_summary; 

WITH firsts AS (
    SELECT ad.sessionid 
     ,ad.activity_desc 
     ,ROW_NUMBER() OVER (ORDER BY ad.created ASC) as RowNumber 
    FROM activity_detail AS ad 
) 
,lasts AS (
    SELECT ad.sessionid 
     ,ad.activity_desc 
     ,ROW_NUMBER() OVER (ORDER BY ad.created DESC) as RowNumber 
    FROM activity_detail AS ad 
) 
insert into activity_summary (sessionid, first_activity_desc, last_activity_summary) 
select a.sessionid 
    ,firsts.activity_desc 
    ,lasts.activity_desc 
from activity AS a 
INNER JOIN firsts ON firsts.sessionid = a.sessionid AND firsts.RowNumber = 1 
INNER JOIN lasts ON lasts.sessionid = a.sessionid AND lasts.RowNumber = 1 
+0

感谢。我不知道为什么我没有想到这一点 - 我想我只是讨厌把选择语句换成像这样的列值。无论哪种情况,查询生成的潜在读取数量都很大 - 这正是我期望减少的。 – Chris 2008-11-25 19:03:21

+0

我会为你做一个没有嵌套查询的。 – 2008-11-25 19:05:36

1
insert into activity_summary 
    (sessionid, first_activity_desc, last_activity_desc) 
select 
    agg.sessionid, 
    adf.activity_description, 
    adl.activity_description 
from 
    (SELECT 
     sessionid, MIN(created) as firstcreated, MAX(created) as lastcreated 
    from 
     activity_detail group by sessionid 
    ) agg 
    JOIN 
    activity_details adf ON agg.sessionid = adf.sessionid AND agg.firstcreated = adf.created 
    JOIN 
    activity_details adl ON agg.sessionid = adl.sessionid AND agg.lastcreated = adl.created 
0

粗略地说,

INSERT等

SELECT a.sessionid,d1.activity_description,d2.activity_description

FROM活性的

JOIN细节D1 ON a.sessionid = d1.sessionid JOIN细节D2 ON a.sessionid = d2.sessionid

WHERE NOT EXISTS
(SELECT 1 FROM细节WHERE的sessionid = a.sessionid并创造< d1.created)

AND NOT EXISTS
(SELECT 1 FROM DETA IL WHERE的sessionid = a.sessionid AND创建> d2.created)

0

或者,

INSERT等

(SELECT描述FROM细节D1 WHERE d1.sessionid = a.sessionid
AND NOT EXISTS (SELECT 1 FROM细节WHERE创建< d1.created))AS DESC1,

(SELECT描述FROM细节D2 WHERE d2.sessionid = a.sessionid
AND NOT EXISTS(SELECT 1 FROM细节D2 WHERE创建> D1。创建))AS desc2

FROM活动

(我喜欢这一个自己。)

相关问题