2011-03-03 27 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) 
) 
)