2010-04-02 203 views
1

我在某些外匯交易數據中遇到SQL Server 2008中的查詢問題。我有一張交易表和一張訂單表。交易需要包含2個或更多訂單。下面的DDL模式和示例數據。查詢時遇到問題

我想要做的是寫一個查詢,顯示每筆交易的點差損益。點數是貨幣的1/1000。所以美元1.3441和1.3442之間的差額在外匯交易中是1點。

交易通常有一個進入訂單和多個退出訂單。例如,如果我以1.6100的匯率買入3手英鎊/美元貨幣對,然後以1.6150賣出1手,在1.6200賣出1手,在1.6250賣出1手,則獲利爲(1.6150 - 1.6100)+(1.6200 - 1.6100)+(1.6250 - 1.6100),或50 + 100 + 150 = 300點利潤。

交易也可能以另一種方式(短路)。例如,貨幣對可以先以較便宜的價格買回,然後再買回來。

我想返回下面的查詢:

tradeId, currencyPair, profitInPips 

這似乎是一個非常簡單的查詢,但它躲避我現在。

這裏是我的DDL和樣本數據:

CREATE TABLE [dbo].[trades](
    [tradeId] [int] IDENTITY(1,1) NOT NULL, 
    [currencyPair] [char](6) NOT NULL, 
CONSTRAINT [PK_trades] PRIMARY KEY CLUSTERED 
(
    [tradeId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 
SET IDENTITY_INSERT [dbo].[trades] ON 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (1, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (2, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (3, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (4, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (5, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (6, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (7, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (8, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (9, N'GBPUSD') 
INSERT [dbo].[trades] ([tradeId], [currencyPair]) VALUES (10, N'GBPUSD') 
SET IDENTITY_INSERT [dbo].[trades] OFF 
GO 
CREATE TABLE [dbo].[orders](
    [orderId] [int] IDENTITY(1,1) NOT NULL, 
    [tradeId] [int] NOT NULL, 
    [amount] [decimal](18, 1) NOT NULL, 
    [buySell] [char](1) NOT NULL, 
    [rate] [decimal](18, 6) NOT NULL, 
    [orderDateTime] [datetime] NOT NULL, 
CONSTRAINT [PK_orders] PRIMARY KEY CLUSTERED 
(
    [orderId] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 
SET IDENTITY_INSERT [dbo].[orders] ON 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (1, 1, CAST(3.0 AS Decimal(18, 1)), N'S', CAST(1.606500 AS Decimal(18, 6)), CAST(0x00009CF40083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (2, 1, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.615500 AS Decimal(18, 6)), CAST(0x00009CF400A4CB80 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (3, 2, CAST(3.0 AS Decimal(18, 1)), N'S', CAST(1.608000 AS Decimal(18, 6)), CAST(0x00009CF500000000 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (4, 2, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.603000 AS Decimal(18, 6)), CAST(0x00009CF50083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (5, 2, CAST(2.0 AS Decimal(18, 1)), N'B', CAST(1.605500 AS Decimal(18, 6)), CAST(0x00009CF50107AC00 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (6, 3, CAST(3.0 AS Decimal(18, 1)), N'S', CAST(1.595500 AS Decimal(18, 6)), CAST(0x00009CF70083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (7, 3, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.590500 AS Decimal(18, 6)), CAST(0x00009CF700C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (8, 3, CAST(2.0 AS Decimal(18, 1)), N'B', CAST(1.594500 AS Decimal(18, 6)), CAST(0x00009CF701499700 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (9, 4, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.611000 AS Decimal(18, 6)), CAST(0x00009CFB0083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (10, 4, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.616000 AS Decimal(18, 6)), CAST(0x00009CFB00A4CB80 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (11, 4, CAST(2.0 AS Decimal(18, 1)), N'S', CAST(1.611500 AS Decimal(18, 6)), CAST(0x00009CFB0107AC00 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (12, 5, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.613000 AS Decimal(18, 6)), CAST(0x00009CFC0083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (13, 5, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.618000 AS Decimal(18, 6)), CAST(0x00009CFC0107AC00 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (14, 5, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.623000 AS Decimal(18, 6)), CAST(0x00009CFC0083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (15, 5, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.628000 AS Decimal(18, 6)), CAST(0x00009CFD00C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (16, 6, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.632000 AS Decimal(18, 6)), CAST(0x00009D020083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (17, 6, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.637000 AS Decimal(18, 6)), CAST(0x00009D0200A4CB80 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (18, 6, CAST(2.0 AS Decimal(18, 1)), N'S', CAST(1.630000 AS Decimal(18, 6)), CAST(0x00009D0200C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (19, 7, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.634500 AS Decimal(18, 6)), CAST(0x00009D0201499700 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (20, 7, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.639500 AS Decimal(18, 6)), CAST(0x00009D0300000000 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (21, 7, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.644500 AS Decimal(18, 6)), CAST(0x00009D030083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (22, 7, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.637500 AS Decimal(18, 6)), CAST(0x00009D0300C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (23, 8, CAST(3.0 AS Decimal(18, 1)), N'S', CAST(1.625000 AS Decimal(18, 6)), CAST(0x00009D0400C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (24, 8, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.620000 AS Decimal(18, 6)), CAST(0x00009D050083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (25, 8, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.615000 AS Decimal(18, 6)), CAST(0x00009D0500A4CB80 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (26, 8, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.623000 AS Decimal(18, 6)), CAST(0x00009D050107AC00 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (27, 9, CAST(3.0 AS Decimal(18, 1)), N'S', CAST(1.618000 AS Decimal(18, 6)), CAST(0x00009D0600C5C100 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (28, 9, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.613000 AS Decimal(18, 6)), CAST(0x00009D0600D63BC0 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (29, 9, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.608000 AS Decimal(18, 6)), CAST(0x00009D0600E6B680 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (30, 9, CAST(1.0 AS Decimal(18, 1)), N'B', CAST(1.613300 AS Decimal(18, 6)), CAST(0x00009D0601391C40 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (31, 10, CAST(3.0 AS Decimal(18, 1)), N'B', CAST(1.614500 AS Decimal(18, 6)), CAST(0x00009D090083D600 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (32, 10, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.619500 AS Decimal(18, 6)), CAST(0x00009D090107AC00 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (33, 10, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.624500 AS Decimal(18, 6)), CAST(0x00009D0901499700 AS DateTime)) 
INSERT [dbo].[orders] ([orderId], [tradeId], [amount], [buySell], [rate], [orderDateTime]) VALUES (34, 10, CAST(1.0 AS Decimal(18, 1)), N'S', CAST(1.619000 AS Decimal(18, 6)), CAST(0x00009D0A0083D600 AS DateTime)) 
SET IDENTITY_INSERT [dbo].[orders] OFF 
/****** Object: ForeignKey [FK_orders_trades] Script Date: 04/02/2010 15:05:31 ******/ 
ALTER TABLE [dbo].[orders] WITH CHECK ADD CONSTRAINT [FK_orders_trades] FOREIGN KEY([tradeId]) 
REFERENCES [dbo].[trades] ([tradeId]) 
GO 
ALTER TABLE [dbo].[orders] CHECK CONSTRAINT [FK_orders_trades] 
GO 

在此先感謝您的幫助!

+0

我固定貿易8,訂單ID 26應該是一個買,不賣。 – 2010-04-02 15:58:18

回答

2

貌似group by會做的伎倆:

select 
    t.tradeId 
, cast(SUM(case buySell 
     when 'S' then 1 
     when 'B' then -1 
     end * o.rate * o.amount) * 1000 as int) as pipsProfit 
from trades t 
join orders o on o.tradeId = t.tradeId 
group by t.tradeId 

這導致:

tradeId pipsProfit 
1 -27 
2 10 
3 7 
4 6 
5 30 
6 1 
7 18 
8 3263 
9 19 
10 19 
+0

完美而優雅,除了答案應乘以10000而不是1000.非常感謝! – 2010-04-02 16:08:49