1

カスケード条件付きロジックを含む SQL ステートメントを作成しようとしています。返す必要のあるフィールドがいくつかありますが、それらの値は以前に決定されたフィールドに基づいています。たとえば、buysell_flag は spotfwd_flag 値に依存し、counter_amt と given_amt は buysell_flag 値に依存するなどです。

データ取得クエリと変数代入クエリを同じ空間で組み合わせることができないことがすぐにわかったので、いろいろ試してみましたが、必要なデータを返すことができませんでした。これは、この SQL を編集してプログラムに貼り付けるクライアント用のテンプレートです。常に同じであるとは限らないため、プログラムまたはストアド プロシージャまたは UDF でロジックを処理できません。テーブルを使用しようとしましたが、それを挿入して選択すると、同じ問題が発生しました。以下の私の試みを見ることができますが、それができない場合はお知らせください。それ以外の場合は、あらゆる提案を受け入れます! ありがとう!

    DECLARE @trans_type nvarchar(255), @trade_date nvarchar(255), @settle_date nvarchar(255), 
@order_id nvarchar(255), @oaexecbroker nvarchar(255), @exec_broker nvarchar(255),
@ostatus nvarchar(255), @trade_id nvarchar(255), @reference_price nvarchar(255), 
@given_ccy nvarchar(255), @spotfwd_flag nvarchar(255), @buysell_flag nvarchar(255),
@counter_ccy nvarchar(255), @counter_amt nvarchar(255), @given_amt nvarchar(255),
@oacct_cd nvarchar(255)

SELECT 
@trans_type = o.trans_type,
@settle_date = o.settle_date,
@order_id = o.order_id,
@oaexecbroker = oa.exec_broker,
@exec_broker = o.exec_broker,
@ostatus = o.status,
@trade_id = oa.trade_id,
@reference_price = o.exec_price,
@given_ccy = o.target_crrncy,

--o.trans_type    AS trans_type, 
--  o.trade_date    AS trade_date, 
--  o.settle_date   AS settle_date, 
--  o.order_id      AS order_id, 
--  oa.exec_broker  AS oaexecbroker, 
--  o.exec_broker   AS exec_broker, 
--  o.status        AS ostatus, 
--  oa.trade_id     AS trade_id, 
--  o.exec_price    AS reference_price, 
--  o.target_crrncy as given_ccy, 
    -- for spot/fwd

    @spotfwd_flag = CASE 
        WHEN LEFT(o.inv_class_cd,1) = 'F' THEN ('FWD')
        WHEN LEFT(o.inv_class_cd,2) = 'CU' THEN ('SPOT')
    ELSE 'SPOT'
    END, -- must be spot or fwd
    --for buysell   

    @buysell_flag = CASE
        WHEN @spotfwd_flag = 'FWD' THEN 
            CASE
                WHEN o.target_crrncy = o.to_crrncy THEN 'BUY'
                ELSE 'SELL'
            END
    ELSE
        CASE 
            WHEN o.trans_type = 'BUYL' THEN 'BUY'
            ELSE 'SELL'
        END
    END, -- must be buy or sell

    @counter_amt = CASE 
        WHEN @buysell_flag = 'BUY' Then oa.exec_amt
        ELSE oa.exec_qty
    END,

    @given_amt = CASE
        WHEN @buysell_flag = 'SELL' THEN oa.exec_amt
        ELSE oa.exec_qty
    END, 

    @counter_ccy = CASE 
        WHEN o.target_crrncy = o.to_crrncy THEN o.from_crrncy
        ELSE o.to_crrncy
    END,

    @oacct_cd = CASE 
        WHEN f.udf_char6 = 'Y' THEN (oa.acct_cd + oa.custodian)
        ELSE oa.acct_cd 
    END 
FROM   ts_order_alloc oa 
    LEFT OUTER JOIN ts_order o 
    ON oa.order_id = o.order_id 
    LEFT OUTER JOIN cs_fund f 
    ON oa.acct_cd = f.acct_cd 
--  LEFT OUTER JOIN csm_security s 
--  ON o.sec_id = s.sec_id 
--WHERE  s.sec_typ_cd IN ( 'CFWD', 'CURR' ) 
--  AND o.status IN ( 'READY','ACCT' ) 
--  AND oa.usr_class_cd_2 = 'GTSSREADY' 

select @trans_type as trans_type,
    @trade_date    AS trade_date, 
    @settle_date   AS settle_date, 
    @order_id      AS order_id, 
    @oaexecbroker  AS oaexecbroker, 
    @exec_broker   AS exec_broker, 
    @ostatus        AS ostatus, 
    @trade_id     AS trade_id, 
    @reference_price   AS reference_price, 
    @given_ccy as given_ccy,
    @buysell_flag as buysell_flag,
    @spotfwd_flag as spotfwd_flag,
    @given_ccy as given_ccy,
    @counter_ccy as counter_ccy,
    @given_amt as given_amt,
    @counter_amt as counter_amt

編集:

指定された変数に基づいて行を取得することを期待しています。私が非常に多くの変数を持っている理由は、それを SQL エラー メッセージに準拠させようとしていたからです。

次のようになります。

trans_type  trade_date  settle_date order_id    oaexecbroker    exec_broker ostatus trade_id    reference_price given_ccy   buysell_flag    spotfwd_flag    given_ccy   counter_ccy given_amt   counter_amt
BUYL    NULL    2010-04-06 00:00:00.000 1442084139  3PCITI  3PCITI  Ready   1389278710  1.50705 GBP BUY SPOT    GBP USD 604292  910699
4

1 に答える 1

0

私がこの問題を正しく理解している場合、あなたがする必要があるのは、後でそれらの計算の結果を使用するために計算のロジックをカプセル化することです。

計算の入力に応じて、これを行うにはさまざまな方法があります。

  • ロジックに単一のテーブルの単一の行内の値のみが含まれる場合は、計算列を定義してロジックをカプセル化できます。これがどのように機能するかSELECTは、計算列の値を指定すると、計算が自動的に行われます。この方法は、同じロジックを頻繁に再利用する必要がある場合に適しています。これは、テーブル構造に対する永続的な変更であるためです。

  • ロジックをカプセル化するための優れた方法は、ビュー内にあります。これは、結果が複数のテーブルのデータを組み合わせる可能性があることを除けば、永続化された列のようなものです。ビューには1つのステートメントしか含めることができないため、SELECTここに示す他のメソッドと組み合わせることができます。

  • 派生テーブル。それは派手に聞こえますが、概念は非常に単純です。ステートメントの結果をSELECT別のステートメントの入力として使用しますSELECT。次の例を見てください。

    DECLARE @test table
    (
        Col1 int,
        Col2 int
    );
    
    -- Result query (2)    
    SELECT
        a.Col1,
        (
            CASE
                WHEN a.Col3 < a.Col1 THEN 1  -- Use the computation
                ELSE 5
            END
        ) AS Col4
        FROM
        (
            -- Derived table (1)
            SELECT
                Col1,
                Col2 + Col1 AS Col3  -- Compute
                FROM @test t1
        ) a;
    

    最も内側のクエリが最初に発生し(1)、外側のクエリ(2)では、内側のクエリの結果を使用できます。計算に「レイヤー」がなくなるまで、ネストを続けます。

  • 共通テーブル式(CTE)。これは派生テーブルに似ていますが、構文が少し異なり、メインクエリでロジックを複数回再利用できます。基本的に、CTEは、単一のクエリに対してのみ存在するビューのようなものです。派生テーブルの代わりにCTEを使用した、上記と同じ例を次に示します。

    DECLARE @test table
    (
        Col1 int,
        Col2 int
    );
    
    WITH a AS
    (
        -- CTE (1)
        SELECT
            Col1,
            Col2 + Col1 AS Col3  -- Compute
            FROM @test t1
    )
        -- Result query (2)    
        SELECT
            a.Col1,
            (
                CASE
                    WHEN a.Col3 < a.Col1 THEN 1  -- Use the computation
                    ELSE 5
                END
            ) AS Col4
            FROM a;
    

投稿したクエリには2つ以上のレイヤーが必要になるため、これらのメソッドのいくつかを組み合わせるか、すべてに派生テーブルを使用する必要がある場合があります。主なことは、これらのメソッドを適用した後、おそらくスカラー変数を使用する必要がないことに気付くでしょう!

于 2013-01-08T03:14:33.823 に答える