我有几个用于记录应用程序用户活动的表。这些表看起来像这样(来自内存的伪代码,可能在语法上不正确):
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;
然而,这对我来说似乎非常冗长和不必要。我只是不确定如何缩小它。我的直觉是我可以在insert语句中以某种方式完成它,但我很难过。有什么建议?
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分:0)
粗略地说,
INSERT等。
SELECT a.sessionid, d1.activity_description, d2.activity_description
FROM activity a
JOIN detail d1 ON a.sessionid = d1.sessionid
JOIN detail d2 ON a.sessionid = d2.sessionid
WHERE NOT EXISTS
(SELECT 1 FROM detail WHERE sessionid = a.sessionid AND created < d1.created)
AND NOT EXISTS
(SELECT 1 FROM detail WHERE sessionid = a.sessionid AND created > d2.created)
答案 3 :(得分:0)
或者,
INSERT等。
(SELECT description FROM detail d1 WHERE d1.sessionid = a.sessionid
AND NOT EXISTS(从创建的详细信息中选择1&lt; d1.created))AS desc1,
(SELECT description FROM detail d2 WHERE d2.sessionid = a.sessionid
AND NOT EXISTS(选择1来自细节d2 WHERE创建&gt; d1.created))AS desc2
FROM activity a
(我自己更喜欢这个。)