Reputation: 29163
I have a table
timestamp ip score 1432632348 1.2.3.4 9 1432632434 5.6.7.8 8 1432632447 1.2.3.4 9 1432632456 1.2.3.4 8 1432632460 5.6.7.8 8 1432632464 1.2.3.4 9
The timestamps are consecutive, but don't have any frequency. I want to count, per IP, the number of times the score changed. so in the example the result would be:
ip count 1.2.3.4 3 5.6.7.8 1
How can I do that? (note: count distinct does not work: 1.2.3.4 changed 3 times but had 2 distinct scores)
Upvotes: 3
Views: 289
Reputation: 33818
Although this requirement is not common, it is not rare either. Basically, you need to determine when there is a change in the data column.
The data is Relational, therefore the solution is Relation. No Cursors or CTEs or ROW_NUMBER()s
or temp tables or GROUP BYs
or scripts or triggers are required. DISTINCT
will not work. The solution is straight-forward. But you have to keep your Relational hat on.
SELECT COUNT( timestamp )
FROM (
SELECT timestamp,
ip,
score,
[score_next] = (
SELECT TOP 1
score -- NULL if not exists
FROM MyTable
WHERE ip = MT.ip
AND timestamp > MT.timestamp
)
FROM MyTable MT
) AS X
WHERE score != score_next -- exclude unchanging rows
AND score_next != NULL
I note that for the data you have given, the output should be:
ip count
1.2.3.4 2
5.6.7.8 0
if you have been counted the last score per ip, which hasn't changed yet, then your figures will by "out-by-1". To obtain your counts, delete that last line of code.
if you have been counting an stated 0
as a starting value, add 1
to the COUNT().
If you interested in more discussion of the not-uncommon problem, I have given a full treatment in this Answer.
Upvotes: 1
Reputation: 44795
select ip,
sum(case when score <> (select t2.score from table t2
where t2.timestamp = (select max(timestamp) from table
where ip = t2.ip
and timestamp < t1.timestamp)
and t1.ip = t2.ip) then 1 else 0 end)
from table t1
group by ip
Upvotes: 2
Reputation: 1923
select ip ,
count(distinct score)
from YourTable
group by ip
Upvotes: -2