วันนี้ระหว่างทำ DS_FTA ลองอ่าน ฺBOT Manual และก็เริ่มลงมือ Query ดึงข้อมูลเลยครับ พอมีข้อมูลแล้วมีกำลังใจเขียน Code ต่อครับ ไม่งั้นมืดมน เพราะ User เองก็ไม่รู้ว่าต้องส่งอะไรให้ BOT แต่พอเขียน Query ไปได้สัก 80% ช่วงประมาณ 4 โมงเย็น อยู่ๆ มี Idea ทำไมเราไม่ลองใช้ CASE WHEN ในการเขียน JOIN Table หละ ถ้ามันทำได้นี่ มันทำให้เราพลิกแพลงได้เยอะมากครับ
ขั้นแรก มาลองหาข้อมูลกันก่อนว่ามีชาวบ้านเค้าทำไหม ? ปรากฏว่ามีด้วยแหละ
เท่าที่ดูเป็นของ MS SQL Server ที่มี และเท่าที่ดู Syntax มันไม่ได้มีคำสั่งเฉพาะตัวนะ เอาหละ พร้อมจะลุยกันดีกว่า โดยสิ่งที่ผมทำ เป็นลักษณะ ดังนี้ครับ
- แบบเดิม - JOIN แบบปกติ
SELECT A.*
FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.COL1 = B.COL1- แบบใหม่ - ลองใช้ CASE WHEN ครับ
SELECT A.*
FROM TABLE_A A
INNER JOIN TABLE_B B
ON A.COL1 = (
CASE WHEN A.COL2 = 'XXX' OR A.COL2 = 'YYY' THEN 'N'
WHEN A.COL2 = 'AAA' OR A.COL2 = 'BBB' THEN 'E'
ELSE 'Y'
END
)มาลองดูโจทย์ในการทำงานจริงของผมดีกว่า (แต่ปรับย่อมาลงมาครับ) ผมมีโจทย์อยู่ว่า หา Leg Type กับ Transaction ที่มีในระบบครับ
- ข้อมูล Leg Type ของ BOT ครับ
| Code | Value | Description |
|---|---|---|
| 182001 | Buy Foreign Currency | นิติบุคคลรับอนุญาตซื้อเงินตราต่างประเทศแลกกับสกุลเงินบาท |
| 182002 | Sell Foreign Currency | นิติบุคคลรับอนุญาตขายเงินตราต่างประเทศแลกกับสกุลเงินบาท |
| 182003 | Cross Currency | การซื้อขายระหว่างเงินตราต่างประเทศ 2 สกุล |
- ข้อมูล Transaction
| Portfolio Code | Transaction Type | FI Arrangement Number | Exchange Rate | Commodity Currency | Commodity Amount | Quote Currency | Quote Amount |
|---|---|---|---|---|---|---|---|
| PING-RISK-MG | BUY | SO52-20160703 | 35.5328 | THB | 3,553,280 | USD | 100,000 |
| PING-RISK-MG | SELL | SO53-20160703 | 35.5328 | USD | 100,000 | THB | 3,553,280 |
| PING-RISK-MG | BUY | SO54-20160703 | 32.3974 | EUR | 100,000 | THB | 3,239,740 |
| PING-RISK-MG | SELL | SO55-20160703 | 32.3974 | EUR | 100,000 | THB | 3,239,740 |
| PING-RISK-MG | BUY | SO56-20160703 | 1.0968 | EUR | 100,000 | USD | 109,680 |
| PING-RISK-MG | SELL | SO57-20160703 | 0.1504 | CNY | 2,000,000 | USD | 300,800 |
- ออกแบบ Table
CREATE TABLE INVESTTX(
`PortfolioCode` varchar(12)
, `TransactionType` varchar(4)
, `FIArrangementNumber` varchar(13)
, `ExchangeRate` Decimal(11,6)
, `CommodityCurrency` varchar(3)
, `CommodityAmount` Decimal(24,6)
, `QuoteCurrency` varchar(3)
, `QuoteAmount` Decimal(24,6)
);
INSERT INTO INVESTTX(
`PortfolioCode`
, `TransactionType`
, `FIArrangementNumber`
, `ExchangeRate`
, `CommodityCurrency`
, `CommodityAmount`
, `QuoteCurrency`
, `QuoteAmount`)
VALUES
('PING-RISK-MG', 'BUY', 'SO52-20160703', 35.5328, 'THB', 3553280, 'USD', 100000),
('PING-RISK-MG', 'SELL', 'SO53-20160703', 35.5328, 'USD', 100000, 'THB', 3553280),
('PING-RISK-MG', 'BUY', 'SO54-20160703', 32.3974, 'EUR', 100000, 'THB', 3239740),
('PING-RISK-MG', 'SELL', 'SO55-20160703', 32.3974, 'EUR', 100000, 'THB', 3239740),
('PING-RISK-MG', 'BUY', 'SO56-20160703', 1.0968, 'EUR', 100000, 'USD', 109680),
('PING-RISK-MG', 'SELL', 'SO57-20160703', 0.1504, 'CNY', 2000000, 'USD', 300800)
;
CREATE TABLE MappingLegType(
`TransactionType` varchar(4)
, `ISCrossCurrency` varchar(1)
, `BOTCode` int
, `BOTValue` varchar(21)
, `BOTDescription` varchar(56)
);
INSERT INTO MappingLegType(
`TransactionType`
, `ISCrossCurrency`
, `BOTCode`
, `BOTValue`
, `BOTDescription`)
VALUES
('BUY', 'N', 182001, 'Buy-Foreign-Currency', 'นิติบุคคลรับอนุญาตซื้อเงินตราต่างประเทศแลกกับสกุลเงินบาท'),
('SELL', 'N', 182002, 'Sell-Foreign-Currency', 'นิติบุคคลรับอนุญาตขายเงินตราต่างประเทศแลกกับสกุลเงินบาท'),
('BUY', 'Y', 182003, 'Cross-Currency', 'การซื้อขายระหว่างเงินตราต่างประเทศ-2-สกุล'),
('SELL', 'Y', 182003, 'Cross-Currency', 'การซื้อขายระหว่างเงินตราต่างประเทศ-2-สกุล')
;- ลองเขียน Query ครับ
SELECT ITX.PortfolioCode
, ITX.TransactionType
, ITX.FIArrangementNumber
, LEGTYPE.BOTCode
, LEGTYPE.BOTValue
, ITX.CommodityCurrency
, ITX.QuoteCurrency
, ITX.ExchangeRate
, ITX.CommodityAmount
, ITX.QuoteAmount
FROM INVESTTX ITX
LEFT OUTER JOIN MappingLegType LEGTYPE
ON LEGTYPE.ISCrossCurrency = (
CASE WHEN ITX.CommodityCurrency = 'THB' OR ITX.QuoteCurrency = 'THB' THEN 'N'
ELSE 'Y'
END
)
AND LEGTYPE.TransactionType = ITX.TransactionType- สำหรับตัวอย่างผม ทำไว้ใน SQL Fiddle โดยผมได้ทดสอบบน MySQL
- สำหรับ MS SQL Server ผมได้ลองใน VM แล้วครับ หากใครอยากทดสอบลองแก้ Table และปรับ Syntax ดูครับ
- ส่วนอันนี้เป็น Query ที่ผมเขียนบน DB2 ครับ ยังไม่ Optimize อะไร
SELECT ITX.PORTFOLIOID
, P.PORTFOLIOCODE
, P.PURPOSE AS PORTFOLIOTYPEID
, PORTTYPE.NAME AS PORTFOLIOTYPECODE
, ITX.INVESTTXID
, ITX.INVESTTXNO
, ITX.SECURITYID
, SEC.SECURITYCODE
, UNDSEC.UNDERLYINGTYPECODE
, INDEXTYPE.INDEXINVOLVEMENTTYPECODE
, ITX.BROKERID
, BR.BROKERCODE AS BROKERCODE
, BRCOM.DSET_ORGANIZATIONID AS BROKERORGANIZATIONID
, BRUNIQUEIDTYPE.CODE AS BROKERUNIQUEIDTYPECODE
, ITX.COUNTERPARTYID
, CTP.COUNTERPARTYCODE AS COUNTERPARTYCODE
, CTPCOM.DSET_ORGANIZATIONID AS COUNTERPARTYORGANIZATIONID
, CTPUNIQUEIDTYPE.CODE AS COUNTERPARTYUNIQUEIDTYPECODE
, EX.BOTFUTUREMARKETCODE AS FUTUREMARKETCODE
, EX.EXCHANGETYPE
, ITX.TRADEDATE
, SEC.MATURITYDATE
, ITX.INVESTTXTYPEID
, ITX.FUTURESPRICE
, ITX.UNIT AS NOOFCONTRACT
, FTA.MULTIPLIER
, ITX.EXCHANGERATE
, ITX.CURRENCYID AS COMMODITYCCYID
, COMCCY.CURRENCYCODE AS COMMODITYCCYCODE
, FTA.QUOTED AS QUOTECCYID
, QUOTECCY.CURRENCYCODE AS QUOTECCYCODE
, LEGTYPE.LEGTYPECODE AS LEGTYPECODE
FROM INVESTTX ITX
LEFT OUTER JOIN PORTFOLIO P
ON ITX.PORTFOLIOID = P.PORTFOLIOID
AND P.ACTIVEFLAG = 'A'
--JOIN TO FIND PORTFOLIO TYPE 10010017
LEFT OUTER JOIN SYSTEMLOOKUP PORTTYPE
ON P.PURPOSE = PORTTYPE.ID
AND PORTTYPE.LOOKUPCATEGORYID = 10010017
AND PORTTYPE.ACTIVEFLAG = 'A'
--JOIN TO FIND PORTFOLIO TYPE 10010017
LEFT OUTER JOIN SECURITY SEC
ON ITX.SECURITYID = SEC.SECURITYID
AND SEC.ACTIVEFLAG = 'A'
LEFT OUTER JOIN SECURITYTYPE ST
ON SEC.SECURITYTYPEID = ST.SECURITYTYPEID
AND ST.ACTIVEFLAG = 'A'
LEFT OUTER JOIN INVESTMENT INV
ON ST.INVESTMENTID = INV.INVESTMENTID
AND INV.ACTIVEFLAG = 'A'
--JOIN FUTURES MASTER
LEFT OUTER JOIN FUTURES FTA
ON SEC.SECURITYID = FTA.SECURITYID
AND FTA.ACTIVEFLAG = 'A'
LEFT OUTER JOIN UNDERLYINGSECURITY UNDSEC
ON FTA.UNDERLYINGSECURITYID = UNDSEC.UNDERLYINGSECURITYID
AND UNDSEC.ACTIVEFLAG = 'A'
--JOIN FUTURES MASTER
--JOIN BROKER DATA
LEFT OUTER JOIN BROKER BR
ON ITX.BROKERID = BR.COMPANYID
AND BR.ACTIVEFLAG = 'A'
LEFT OUTER JOIN COMPANY BRCOM
ON BR.COMPANYID = BRCOM.COMPANYID
AND BRCOM.ACTIVEFLAG = 'A'
--FIND UNIQUE ID TYPE 10026094
LEFT OUTER JOIN SYSTEMLOOKUP BRUNIQUEIDTYPE
ON BRCOM.DSET_INVOLVEDPARTYTYPEID = BRUNIQUEIDTYPE.ID
AND BRUNIQUEIDTYPE.LOOKUPCATEGORYID = 10026094
AND BRUNIQUEIDTYPE.ACTIVEFLAG = 'A'
--FIND UNIQUE ID TYPE 10026094
--JOIN BROKER DATA
--JOIN COUNTER PARTY DATA
LEFT OUTER JOIN COUNTERPARTY CTP
ON ITX.COUNTERPARTYID = CTP.COUNTERPARTYID
LEFT OUTER JOIN COMPANY CTPCOM
ON CTP.REFERENCEID = CTPCOM.COMPANYID
AND CTPCOM.ACTIVEFLAG = 'A'
--FIND UNIQUE ID TYPE 10026094
LEFT OUTER JOIN SYSTEMLOOKUP CTPUNIQUEIDTYPE
ON CTPCOM.DSET_INVOLVEDPARTYTYPEID = CTPUNIQUEIDTYPE.ID
AND CTPUNIQUEIDTYPE.LOOKUPCATEGORYID = 10026094
AND CTPUNIQUEIDTYPE.ACTIVEFLAG = 'A'
--FIND UNIQUE ID TYPE 10026094
--JOIN COUNTER PARTY DATA
--JOIN EXCHANGE
LEFT OUTER JOIN EXCHANGE EX
ON FTA.EXCHANGEID = EX.EXCHANGEID
AND EX.ACTIVEFLAG = 'A'
--JOIN EXCHANGE
--COMMODITY CURRENCY
LEFT OUTER JOIN CURRENCY COMCCY
ON ITX.CURRENCYID = COMCCY.CURRENCYID
AND COMCCY.ACTIVEFLAG = 'A'
--COMMODITY CURRENCY
--QUOTE CURRENCY
LEFT OUTER JOIN CURRENCY QUOTECCY
ON FTA.QUOTED = QUOTECCY.CURRENCYID
AND QUOTECCY.ACTIVEFLAG = 'A'
--QUOTE CURRENCY
--JOIN TO FIND INDEX INVOLVEMENT
LEFT OUTER JOIN DSET_MAPPARAM_INDEXINVOLVEMENTTYPE INDEXTYPE
ON INV.INTERNALCODE = INDEXTYPE.INTERNALCODE
AND UNDSEC.UNDERLYINGTYPECODE = INDEXTYPE.UNDERLYINGTYPECODE
AND INDEXTYPE.DATASETTYPE = 'FTA'
AND INDEXTYPE.ISENABLE = 'Y'
--JOIN TO FIND INDEX INVOLVEMENT
--JOIN TO FIND ARRANGEMENT BY PRODUCT-FUTURE
LEFT OUTER JOIN DSET_MAPPARAM_ARRANGEMENTTYPE_FTA ARR_FTA
ON INV.INTERNALCODE = ARR_FTA.INTERNALCODE
AND UNDSEC.UNDERLYINGTYPECODE = ARR_FTA.UNDERLYINGTYPECODE
AND ARR_FTA.ISENABLE = 'Y'
AND ARR_FTA.DATASETTYPE = 'FTA'
--JOIN TO FIND ARRANGEMENT BY PRODUCT-FUTURE
--JOIN TO FIND ARRANGEMENT BY TX TYPE
LEFT OUTER JOIN DSET_MAPPARAM_ARRANGEMENTTYPE_TX ARR_TX
ON ITX.INVESTTXTYPEID = ARR_TX.TXTYPEID
AND ARR_TX.ISENABLE = 'Y'
AND ARR_TX.DATASETTYPE = 'FTA'
--JOIN TO FIND ARRANGEMENT BY TX TYPE
--JOIN TO FIND LEGTYPE
LEFT OUTER JOIN DSET_MAPPARAM_LEGTYPE LEGTYPE
ON LEGTYPE.ISCROSSCURRENCY = (
CASE WHEN ITX.CURRENCYID = 1 OR FTA.QUOTED = 1 THEN 'N'
ELSE 'Y'
END
)
AND LEGTYPE.TXARRANGEMENTTYPEID = ARR_TX.ARRANGEMENTTYPEID
AND LEGTYPE.PRODUCTARRANGEMENTTYPEID = ARR_FTA.ARRANGEMENTTYPEID
AND LEGTYPE.ISENABLE = 'Y'
AND LEGTYPE.DATASETTYPE = 'FTA'
--JOIN TO FIND LEGTYPE
WHERE ITX.ISDELETED = 'N'
AND ITX.ISCANCELLED = 'N'
AND ITX.ISPOSTED = 'Y'
AND ITX.TRADEDATE = '2016-02-01'
AND ITX.PORTFOLIOID = 201
AND INDEXTYPE.CONFIGID IN (SELECT TINDEXTYPE.CONFIGID
FROM DSET_MAPPARAM_INDEXINVOLVEMENTTYPE TINDEXTYPE
WHERE TINDEXTYPE.ISENABLE = 'Y'
AND TINDEXTYPE.DATASETTYPE = 'FTA'
AND INV.INTERNALCODE = TINDEXTYPE.INTERNALCODE
AND UNDSEC.UNDERLYINGTYPECODE = TINDEXTYPE.UNDERLYINGTYPECODE)หมายเหตุ : ผมยังไม่ได้สนใจ Performance และอาจจะมีวิธีอื่นๆ ที่ทำได้ดีกว่านะครับ ที่เขียน Blog เพื่อไปเป็นแนวทาง สำหรับการไปประยุกต์ใช้ครับ ^__^
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.



