Is it possible to write union select queries like the following more succintly?
select
id,
1,
(1 + @defCapUp) * (p.Value + p.Premium),
getdate()
from Products p
union
select
id,
1,
(1 - @defCapDown) * (p.Value - p.Premium),
getdate()
from Products p
union
select
id,
case when p.Paydate > getdate() then 1 else 0 end,
(1 - @defCapUp) * (p.Value - p.Premium),
@nextYear
from Products p
union
select
id,
case when p.Paydate > getdate() then 1 else 0 end,
(1 + @defCapDown) * (p.Value + p.Premium),
@nextYear
from Products p
The statement selects four rows for each row in the Products table. The only thing varying is the formula used to calculate the values for column two and tree. I think there should be a way in sql to write the above without so much ugly code duplication. If only functions were first class objects and sql allowed lambda expressions…
Richard’s solution down below is perfect, works very well for the example provided. But I had two typos in the orignal example which makes the problem somewhat tougher:
select
id,
1,
(1 + @defCapUp) * (p.Value + p.Premium),
getdate()
from Products p
union
select
id,
1,
(1 - @defCapDown) * (p.Value - p.Payout),
getdate()
from Products p
union
select
id,
case when p.Paydate > getdate() then 1 else 0 end,
(1 - @defCapUp) * (p.Value - p.Premium),
@nextYear
from Products p
union
select
id,
case when p.Paydate <= getdate() then 1 else 0 end,
(1 + @defCapDown) * (p.Value + p.Payout),
@nextYear
from Products p
The big problem is the case expression in which the comparison operator differs. My problem is that it is very hard to “neatly” handle those cases. What if there were a third case where the comparison was p.Paydate = getdate() for example?
(Not sure how lambda expressions would have helped you)
BTW, you should have been using UNION ALL, not UNION.