我正在建立一个小型数据库交易系统,我遇到了重复问题,我不确定如何解决。基本上我有一个价格表与价格设定的日期时间表,我还有一个表格与交易时间。我希望根据交易日期时间得到正确的价格。
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Trade] Script Date: 06/30/2012 14:49:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Trade](
[trade_id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[trade_volume] [int] NOT NULL,
[trade_action] [varchar](5) NOT NULL,
[trade_date] [datetime] NOT NULL,
[timestap] [timestamp] NOT NULL,
[trader_id] [int] NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
CONSTRAINT [PK_Trades] PRIMARY KEY CLUSTERED
(
[trade_id] 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
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Contract]
GO
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Trader] FOREIGN KEY([trader_id])
REFERENCES [dbo].[Trader] ([trader_id])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Trader]
GO
ALTER TABLE [dbo].[Trade] ADD CONSTRAINT [DF_Trades_trade_id] DEFAULT (newid()) FOR [trade_id]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Contract] Script Date: 06/30/2012 14:56:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Contract](
[exch_ticker] [varchar](8) NOT NULL,
[exch_name] [varchar](50) NULL,
[portfolio_id] [varchar](8) NOT NULL,
[region_cd] [varchar](5) NULL,
CONSTRAINT [PK_Contract] PRIMARY KEY CLUSTERED
(
[exch_ticker] 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
ALTER TABLE [dbo].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_portfolio] FOREIGN KEY([portfolio_id])
REFERENCES [dbo].[portfolio] ([portfolio_id])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_portfolio]
GO
ALTER TABLE [dbo].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_region] FOREIGN KEY([region_cd])
REFERENCES [dbo].[Region] ([region_cd])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_region]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[price_details] Script Date: 06/30/2012 14:58:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[price_details](
[price_id] [int] IDENTITY(1,1) NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
[price_set_date] [datetime] NOT NULL,
[buy_price] [decimal](7, 2) NOT NULL,
[sell_price] [decimal](7, 2) NOT NULL,
CONSTRAINT [PK_price_detail] PRIMARY KEY CLUSTERED
(
[price_id] 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
ALTER TABLE [dbo].[price_details] WITH CHECK ADD CONSTRAINT [FK_price_details_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[price_details] CHECK CONSTRAINT [FK_price_details_Contract]
GO
查看
USE [a_trading_system]
GO
/****** Object: View [dbo].[V_all_uk] Script Date: 06/30/2012 14:39:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER VIEW [dbo].[V_all_uk]
AS
SELECT distinct
co.exch_ticker,
--co.region_cd,
po.portfolio_type,
r.region_name,
r.currency,
t.trade_id,
t.trade_volume,
t.trade_action,
t.trade_date,
pr.buy_price,
--(select distinct pr.buy_price from price_details pr
--where pr.price_set_date <= t.trade_date or pr.price_set_date >= t.trade_date) as price_details,
--MIN(t.trade_date) as trade_date,
--pr.buy_price,
--pr.sell_price,
--pr.price_set_date, --This is the cause of duplication
--pr.price_set_time,case when t.trade_date IS NOT NULL then
--case
--when t.trade_action = 'Buy' then
--t.trade_volume * max(pr.buy_price)
--else
--case when trade_action = 'Sell' then
--t.trade_volume * max(pr.sell_price)
--end
--end as 'trade_value' ,
tr.trader_name,
tr.trader_address,
tr.phone
FROM dbo.Contract as co
INNER JOIN dbo.Portfolio as po ON co.portfolio_id = po.portfolio_id
INNER JOIN dbo.region as r ON co.region_cd = r.region_cd
INNER JOIN dbo.Trade as t ON co.exch_ticker = t.exch_ticker
INNER JOIN dbo.trader as tr ON t.trader_id = tr.trader_id
inner join dbo.price_details as pr on pr.exch_ticker = t.exch_ticker
where r.region_cd = 'UK'
--group by
--co.exch_ticker,
--co.region_cd,
--po.portfolio_type,
--r.region_name,
--r.currency,
--t.trade_id,
--t.trade_volume,
--t.trade_action,
--pr.buy_price,
--pr.sell_price,
--tr.trader_name,
--tr.trader_address,
--tr.phone
GO
如果您需要查看数据,这些是三个主要表格,因为我通常不会在此网站上发布SQL问题。
解释
如果价格设置为12:20且价格为100,那么在12:40,价格为80.这是两个日期范围。因此,如果我在12:30购买,那么我以100的价格购买,因为这是最后的价格。我也在视图中进行连接,所以我可以看到所有数据。我现在就发布。
由于
答案 0 :(得分:1)
要在特定交易日期之前获得最新价格:
select buy_price, sell_price
from price_details
where exch_ticker = @exch_ticker and price_set_date =
( select max( price_set_date )
from price_details
where exch_ticker = @exch_ticker and price_set_date <= @trade_date )
您可能希望将exch_ticker
/ trade_date
(desc)的索引添加到price_details
。
答案 1 :(得分:0)
以下假定SQL Server 2005或更高版本。
首先要加入Trade
和price_details
过滤掉时间大于相应交易次数的价格:
SELECT ...
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
上面的内容将为您提供一个行集,其中每笔交易的所有价格都可以达到交易时间。现在只需对价格进行排名并获得最新价格:
WITH trade_prices AS (
SELECT
t.*, -- actually you might want to review the list
pr.price_set_date, -- of columns being pulled from the two tables
pr.buy_price,
pr.sell_price,
rnk = ROW_NUMBER() OVER (PARTITION BY t.trade_id ORDER BY pr.price_set_date DESC)
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
)
SELECT *
FROM trade_prices
WHERE rnk = 1
要将此功能合并到您的视图中,您只需:
1)添加trade_prices
CTE,
2)将两个联接替换为Trade
和price_details
,并加入trade_prices
,
3)将trade_prices.rnk = 1
条件添加到WHERE
子句中。
当然,trader
表格现在将加入trade_prices
而不是Trade
。您还需要将视图选择列表中的表别名pr
和t
更改为您选择分配给trade_prices
的那个。