Reputation: 17220
I have an excel function: =Max(0, -Min(A1-B1, C1-B1))
and A1,B1,C1 are the Value column in the table:
Date, Key, Value
assume for now the Date is irrelevant and the Key is A,B,C for A1,B1,C1
How do I implement this excel function? The way I originally did it I had two joins (to get the values all in separate columns on the same row) but this seemed like overkill and there must be a smarter way?
Upvotes: 2
Views: 69
Reputation: 1269503
Your question is suggesting a separate value for each row. If so, then this is the query:
select t.*
(case when -leastval < 0 then 0
else -lesatval
end) as TheValue
end
from (select t.*,
(case when A1 - B1 < C1 and A1 - B2 < B1 then A1 - B1
when C1 < B1 then C1
else B1
end) as leastval
from table t
) t
Now that I read the question right, let me assume that there is one value of A, B, and C per date. Then you would use a variation on the above, by simply denomalizing the data first:
select t.*
(case when -leastval < 0 then 0
else -leastval
end) as TheValue
end
from (select t.*,
(case when A - B < C and A - B < B then A - B
when C < B then C
else B
end) as leastval
from (select date,
min(case when key = 'A' then value end) as A,
min(case when key = 'B' then value end) as B,
min(case when key = 'C' then value end) as C
from table t
group by date
) t
) t
There are other ways to formulate this. I tried to stay reasonably close to the Excel formulation.
By the way, some other databases offer Greatest() and Least() functions which may such a formula much easier to create.
Upvotes: 1
Reputation: 238058
You could probably reduce it to one join, since you only need B
for the A
part:
select case
when min(Value - isnull(yt2.Value,0)) > 0 then 0
else -min(Value - isnull(yt2.Value,0))
end
from YourTable yt1
join YourTable yt2
on yt1.Key = 'A' and yt2.key = 'B'
or
yt1.Key = 'B' and yt2.key = 'C'
Upvotes: 2