2012-06-30 3 views
1

Je fais un petit système de négociation de base de données et j'ai un problème avec la duplication dont je ne sais pas comment résoudre. Fondamentalement, j'ai une table avec des prix avec la date à laquelle ce prix a été fixé et j'ai aussi une table avec le temps d'une transaction. Je veux obtenir le prix correct basé sur le commerce date/heure.T-SQL obtenir le prix entre deux dates

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 

Voir

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 

Ce sont les trois principaux tableaux si vous avez besoin de voir les données aussi bien dire parce que je ne posterai pas habituellement des questions SQL sur ce site.

Explication

Si un prix est fixé à 12h20 et le prix est 100 alors au prix est 12h40 80. Ce sont deux plages de dates. Donc si j'achète à 12h30 alors j'achète au prix de 100 car c'est le dernier prix. Je fais aussi mes jointures dans une vue afin que je puisse voir toutes les données. Je vais poster ça maintenant.

Merci

+0

Jetez un oeil à ma publication mise à jour. J'ai créé une vue avec ma logique de base de données, mais j'ai des lignes en double. –

+0

Quelqu'un peut-il aider? –

Répondre

1

Pour obtenir le dernier prix avant une date commerciale particulière:

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) 

Vous pouvez ajouter un index sur exch_ticker/trade_date (desc) à price_details.

+0

Je peux voir ce que vous faites, mais comment pourrais-je l'appliquer à mon avis? –

+0

Changez la vue pour 'JOIN' price_details' avec la logique supplémentaire pour sélectionner un prix approprié et ramasser le' exch_ticker' et 'trade_date' de' trade as t'. Rapidement. – HABO

+0

Je me sens vraiment stupide en ce moment pourriez-vous me montrer un exemple? Tout ce que je veux faire est de montrer le prix correct basé sur la date de transaction en utilisant la vue. –

0

Ce qui suit suppose que SQL Server 2005 ou version ultérieure.

L'idée est d'abord de se joindre Trade et price_details filtrant les prix dont les temps sont plus grandes que les temps de métiers correspondants:

SELECT ... 
FROM dbo.Trade t 
    INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker 

ci-dessus vous obtiendrez un jeu de ligne où tous les métiers a obtenu tous les prix à la hausse au moment du commerce. Maintenant, rang que les prix et obtenir le dernier:

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 

Pour intégrer dans votre vue, vous aurez seulement besoin de:

1) ajouter le trade_prices CTE,

2) remplacer deux rejoint, à Trade et price_details, avec une jointure à trade_prices,

3) ajouter la condition trade_prices.rnk = 1 à la clause WHERE.

Bien sûr, le tableau trader va maintenant être joint à trade_prices au lieu de Trade. Et vous devrez également modifier les alias de table pr et t dans la liste de sélection de la vue à celle que vous choisissez d'attribuer à trade_prices.

+0

Votre hypothèse est correcte. Je regarderai aussi votre solution pour voir si je la trouve plus utile. –