Reputation: 3046
I have a claimstable
like the following.
Time Terminal_ID Claims Count
-------------------------------------------
2017-10-19 06:03:00 1 451 1
2017-10-19 06:04:00 1 452 2
2017-10-19 06:05:00 1 452.3 2
2017-10-19 06:06:00 1 458 2
2017-10-19 06:03:00 9 459 6
2017-10-19 06:04:00 9 461.2 5
2017-10-19 06:05:00 9 462 2
2017-10-19 06:06:00 9 463 1
I select time
, claim
and create a new column Claims_Change
from my table. After this, I insert it into a temporary table.
My expected output would be:
Time Terminal_ID Claims Count Claims_change
---------------------------------------------------------
2017-10-19 06:03:00 1 451 1 Null
2017-10-19 06:04:00 1 452 2 1
2017-10-19 06:05:00 1 452.3 2 0.3
2017-10-19 06:06:00 1 458 2 5.7
2017-10-19 06:03:00 9 459 6 Null
2017-10-19 06:04:00 9 461.2 5 2.2
2017-10-19 06:05:00 9 462 2 0.8
2017-10-19 06:06:00 9 463 1 1
This is my query:
select
[Time], Terminal_ID, Claims,
convert(decimal(12, 3), y.[Claims] - (select t1.[Claims]
from claimstable t1
where t1.Terminal_ID = y.Terminal_ID
and t1.[Time] = (select max([Time])
from claimstable t2
where t2.Terminal_ID = t1.Terminal_ID
and t2.[Time] < y.[Time])
)) as Claims_change
into
#temptable
from
claimstable as y
When I tested this for 5000 rows, it works fine, however, when I test this with 100,000 rows, I get an error like this,
Msg 512, Level 16, State 1, Line 42
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I was reading some older posts, the recommended answer was to use inner join
.
Also, in my case, I don't know how to exactly write to get Claims_change
variable using inner join
.
Any help would be awesome.
Upvotes: 0
Views: 2160
Reputation: 13393
You can try this.
select
[Time], Terminal_ID, y.Claims, convert(decimal(12,3), y.[Claims]- t2.[Claims] ) as Claims_change
into
#temptable
from
claimstable as y
OUTER APPLY ( SELECT TOP 1 t1.[Claims] FROM claimstable t1 where
t1.Terminal_ID = y.Terminal_ID AND y.[Time] > t1.[Time] ORDER BY [Time] DESC ) as t2
Result:
Time Terminal_ID Claims Claims_change
----------------------- ----------- ------------ ---------------
2017-10-19 06:03:00.000 1 451.00 NULL
2017-10-19 06:04:00.000 1 452.00 1.000
2017-10-19 06:05:00.000 1 452.30 0.300
2017-10-19 06:06:00.000 1 458.00 5.700
2017-10-19 06:03:00.000 9 459.00 NULL
2017-10-19 06:04:00.000 9 461.20 2.200
2017-10-19 06:05:00.000 9 462.00 0.800
2017-10-19 06:06:00.000 9 463.00 1.000
Upvotes: 1
Reputation: 49260
If the version of SQL Server you are on supports LAG
, use
select t.*,t.claims-lag(t.claims) over(partition by terminal_id order by time) as claims_change
from claimstable t
LAG
gets the value of a specified column from the previous row based on a specified ordering and partitioning. LAG
for first row (in a partition) will be NULL
. You can use the optional argument to specify a default value.
Upvotes: 1