Reputation: 3121
I have two tables, Link and Hit. The Hit table contains information about when links from Link were hit. The Link table contains a column HitsCount with the number of times each link has been hit. We regularly aggregate Hit's data into aggregations of data for each hour of hits, and remove the aggregated data to save space. When we aggregate, we want to also update Link.HitsCount with the COUNT() of links for the current hour we are aggregating over. How is this done?
Here is my current attempt, using T-SQL:
DECLARE cc CURSOR LOCAL FOR
SELECT COUNT(*) AS c, h.LinkId AS id
FROM Hit AS h
WHERE h.[Timestamp] >= @p_startTime AND h.[Timestamp] < @p_endHour
GROUP BY h.LinkId
OPEN cc
FETCH cc
UPDATELink
SET Link.HitsCount = HitsCount + c
FROM Link
WHERE CURRENT OF cc
CLOSE cc
DEALLOCATE cc
However, I get the error "Invalid column name 'c'." Also, this approach does not JOIN ON h.LinkId and Link.LinkId like it should. I've thought about dropping and populating a scratch table with the LinkId and COUNT(), but I'd rather avoid this. On the other hand, I'd also rather avoid a CURSOR.
Many thanks.
Nathan
Upvotes: 1
Views: 575
Reputation: 9933
there is no need for a cursor, you should be doing something like
UPDATE Link
SET HitsCount = HitsCount + (SELECT COUNT(1) FROM Hit
WHERE Hit.LinkId = Link.Id
AND Hit.[Timestamp] >= @p_startTime
AND Hit.[Timestamp] < @p_endHour)
or
;WITH Hits AS
(
SELECT COUNT(1) AS freq, h.LinkId
FROM Hit AS h
WHERE h.[Timestamp] >= @p_startTime AND h.[Timestamp] < @p_endHour
GROUP BY h.LinkId
)
UPDATE l
SET l.HitCount = l.HitCount + h.freq
FROM Link l
JOIN Hits h ON h.LinkId = l.Id
Upvotes: 3
Reputation: 780798
Use a JOIN with a subquery:
UPDATE Link l
JOIN (SELECT LinkId, COUNT(*) HitsCount
FROM Hit
WHERE h.[Timestamp] >= @p_startTime AND h.[Timestamp] < @p_endHour
GROUP BY LinkID) h
USING (LinkId)
SET l.HitsCount = l.HitsCount + h.HitsCount
Upvotes: 1