2011-03-03 17 views
0

是否可以像下面這樣更靈活地編寫union select查詢?爲沒有聯合的每行選擇x次

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 

該語句爲Products表中的每一行選擇四行。唯一不同的是用於計算第二列和第二列值的公式。我認爲在sql中應該有一種方法來編寫上述代碼,而不會有太多難看的代碼重複。如果只有函數是第一類對象並且sql允許lambda表達式...

理查德的解決方案在下面是完美的,對於提供的示例非常有效。但我曾在一部開拓創新的例子,這使得這個問題有點強硬2個錯別字:

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 

最大的問題是這樣表達:在比較操作不同。我的問題是很難「整齊地」處理這些情況。如果有第三種情況比較是p.Paydate = getdate()例如呢?

回答

3

(不知道怎麼表達拉姆達會幫助你)

select 
    id, 
    case when p.Paydate > X.CompareDate then 1 else 0 end, 
    (1 + Cap) * (p.Value + ModF * p.Premium), 
    @nextYear 
from Products p 
cross join (
    select @defCapUp Cap, Cast(0 as datetime) CompareDate, 1 Modf union all 
    select [email protected], 0, -1 union all 
    select [email protected], GETDATE(), -1 union all 
    select @defCapDown, GETDATE(), 1 
    ) X 

BTW,你應該使用UNION ALL,UNION不已經。

0

如果訂單無關緊要,您可以使用WHERE

SELECT id, field2, field3, field4 
FROM Products p 
WHERE (
    field4 = getdate() AND field2=1 AND 
    (
    field3=(1 + @defCapUp) * (p.Value + p.Premium) OR 
    field3=(1 - @defCapDown) * (p.Value - p.Premium) 
) 
) 
OR 
(
    [email protected] AND field2=(case when p.Paydate > getdate() then 1 else 0 end) AND 
    (
    field3=(1 - @defCapUp) * (p.Value - p.Premium) OR 
    field3=(1 + @defCapDown) * (p.Value + p.Premium) 
) 
)