2013-01-07 15 views
1

我想寫一個SQL語句,它有一些級聯條件邏輯。我有幾個需要返回的字段,但它們的值是以前確定的字段爲條件的。例如,buysell_flag取決於spotfwd_flag值,counter_amt和given_amt取決於buysell_flag值,依此類推。SQL使用局部變量選擇數據檢索

我很快發現我無法在同一空間中組合數據檢索查詢和變量賦值查詢,所以我嘗試了各種各樣的事情,但無法返回我想要的數據。這是客戶端的模板,他們將編輯此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 
+0

局部變量的限制是什麼?上帝,你有很多...兩件事會幫助你在這裏發佈(更新問題)1.表格模式與一些示例數據2.預期的結果... – bonCodigo

+0

謝謝,我刪除了一些並添加了預期的結果。表架構是waaaaay大到後。 – user576838

+0

你究竟在做什麼?我不明白你是否想用數據或一組變量返回一個行集。既然你的問題似乎是關於一般概念,而不是這個特定的查詢,你能否提供一個最小的,虛假的數據示例來說明你的問題?它不必與您的真實表格或數據有任何關係。 – Pondlife

回答

0

如果我正確認識這個問題,你需要做的是封裝計算的邏輯,以後使用這些計算的結果。

根據計算的輸入,有很多不同的方法可以做到這一點。

  • 如果邏輯只在一個表中的單個行中涉及的值,你可以定義一個computed column封裝邏輯。這是如何工作的,當你計算欄的值爲SELECT時,計算是自動完成的。這種方法適用於需要非常頻繁地重複使用相同邏輯的情況,因爲這是對錶結構的永久性更改。

  • 封裝邏輯的好方法是在視圖中。這就像一個持久的列,除了結果可以結合多個表中的數據。由於視圖只能包含單個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層,所以你可能需要結合一些查詢這些方法,或只是使用派生表的一切。主要的是,應用這些方法後,你可能會發現不需要使用任何標量變量!