我正在写一个proc。 proc计算我的数据库中某些活动的发生次数。数据库中但未使用的任何活动都将从数据库中删除:
-- make table variable of occurrences
DECLARE @occs TABLE(ActID int, Occurances int)
INSERT INTO @occs(ActID,Occurances)
(SELECT Activities.ActivityID, COUNT(Users.ActivityID) AS Occurances
FROM Users JOIN Activities ON Users.ActivityID = Activities.ActivityID
GROUP BY Activities.ActivityID)
-- Delete any activities that no one uses
DELETE FROM Activities WHERE ActivityId NOT IN (SELECT ActID FROM @occs)
最终结果(显示在我的网站上)看起来有点像StackOverflow标签系统 - 它显示每个活动的名称以及执行该活动的人数。
并非所有用户都应包含在每项活动的人数中。但是,如果他们是执行该活动的唯一用户,则不应删除该活动。因此,在上一个查询运行之后,我必须再次填充出现表:
INSERT INTO @occs(ActID,Occurances)
(SELECT Activities.ActivityID, COUNT(Users.ActivityID) AS Occurances
FROM Users
JOIN Activities ON Users.ActivityID = Activities.ActivityID
WHERE (Users.CountsTowardsActivityTotal = 1)
GROUP BY Activities.ActivityID)
输出@occs
表的这个版本:
-- return relevant results.
SELECT a2.ActivityID, a2.ActivityName, occs.Occurances
FROM
@occs occs JOIN Activities a2 on occs.ActID = a2.ActivityID
ORDER BY
a2.Activity
因此,我需要在第一次填充后删除@occs
表中的所有行,并输入新数据。或者,我可以创建一个新的表变量(occs2
)并改为使用它。
正确的做法是什么?它有所作为吗?
答案 0 :(得分:2)
根据我的经验,DELETE总是花费更多,所以我可能只是创建一个新的。但是,我认为根本不需要填充第一遍的表变量。
--removes activities not used
DELETE FROM Activities
FROM Activities LEFT JOIN Users ON Activities.ActivityID = Users.ActivityID
WHERE Users.ActivityID IS NULL
--do final select
答案 1 :(得分:2)
为什么有这么多的表变量和聚合以及程序步骤?
你的第一双是:
如果您在使用简单语言编码之前考虑这一点,则“删除没有用户关联的地方”:
DELETE FROM Activities WHERE NOT EXISTS
(SELECT * FROM Users U WHERE U.ActivityID = Activities.ActivityId)
您的第二个可以在一个查询中完成。只需将Activities.ActivityName添加到GROUP BY:
SELECT
Activities.ActivityID, Activities.ActivityName, COUNT(Users.ActivityID) AS Occurances
FROM
Users
JOIN Activities ON Users.ActivityID = Activities.ActivityID
WHERE
(Users.CountsTowardsActivityTotal = 1)
GROUP BY
Activities.ActivityID, Activities.ActivityName
ORDER
Activities.ActivityName