0

次のようなユニオンセレクトクエリをもっと簡潔に書くことは可能ですか?

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テーブルの各行に対して4つの行を選択します。変化するのは、列2とツリーの値を計算するために使用される式だけです。それほど醜いコードの重複なしに上記を書く方法がSQLにあるべきだと思います。関数のみがファーストクラスのオブジェクトであり、SQLでラムダ式が許可されている場合...

以下のリチャードのソリューションは完璧であり、提供された例では非常にうまく機能します。しかし、元の例では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番目のケースがあった場合はどうなりますか?

4

2 に答える 2

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 -@defCapDown, 0, -1 union all
    select -@defCapUp, GETDATE(), -1 union all
    select @defCapDown, GETDATE(), 1
    ) X

ところで、UNIONではなくUNIONALLを使用する必要がありました。

于 2011-03-03T18:53:32.770 に答える
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
(
  field4=@nextYear 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)
  )
)
于 2011-03-03T19:20:10.020 に答える