2010-06-14 6 views
3

Supposons que je le tableau suivant:obtenez des dates qui ne se chevauchent varie pour les prix des données historiques

CREATE TABLE [dbo].[PricesHist] 
(
    [Product] [varchar](6) NOT NULL, 
    [Price] [float] NOT NULL, 
    [StartDate] [datetime] NOT NULL, 
    [EndDate] [datetime] NOT NULL 
) 


INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D2C00000000 AS DateTime), CAST(0x00009D2C00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D2D00000000 AS DateTime), CAST(0x00009D2D00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 2.5, CAST(0x00009D2E00000000 AS DateTime), CAST(0x00009D2E00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3000000000 AS DateTime), CAST(0x00009D3000000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3100000000 AS DateTime), CAST(0x00009D3100000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3400000000 AS DateTime), CAST(0x00009D3400000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 2.5, CAST(0x00009D3500000000 AS DateTime), CAST(0x00009D3500000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3600000000 AS DateTime), CAST(0x00009D3600000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3700000000 AS DateTime), CAST(0x00009D3700000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3800000000 AS DateTime), CAST(0x00009D3800000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3A00000000 AS DateTime), CAST(0x00009D3A00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3B00000000 AS DateTime), CAST(0x00009D3B00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 2.5, CAST(0x00009D3C00000000 AS DateTime), CAST(0x00009D3C00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3D00000000 AS DateTime), CAST(0x00009D3D00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3E00000000 AS DateTime), CAST(0x00009D3E00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D3F00000000 AS DateTime), CAST(0x00009D3F00000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4100000000 AS DateTime), CAST(0x00009D4100000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4200000000 AS DateTime), CAST(0x00009D4200000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 2.5, CAST(0x00009D4300000000 AS DateTime), CAST(0x00009D4300000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4400000000 AS DateTime), CAST(0x00009D4400000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4500000000 AS DateTime), CAST(0x00009D4500000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4600000000 AS DateTime), CAST(0x00009D4600000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 4.9, CAST(0x00009D4800000000 AS DateTime), CAST(0x00009D4800000000 AS DateTime)) 
INSERT [dbo].[PricesHist] ([Product], [Price], [StartDate], [EndDate]) VALUES (N'Apples', 2.5, CAST(0x00009D4A00000000 AS DateTime), CAST(0x00009D4A00000000 AS DateTime)) 

Comme vous pouvez le voir, il y a deux prix sur ce mois pour les pommes. 4,90 et 2,50. Afin de ranger cette table, je dois obtenir cette information comme une plage de dates plutôt qu'une rangée par jour comme c'est actuellement.

Je peux évidemment le faire avec les agrégats Min et Max facilement, mais les plages se chevauchent et d'autres codes d'entreprise attendent des plages sans chevauchement. J'ai aussi essayé d'y parvenir avec auto-jointures et row_number(), mais sans beaucoup de succès ...

Voici ce que je suis en train de réaliser que la sortie:

Product | StartDate | EndDate | Price 
------------------------------------------- 
Apples | 01 Mar 2010 | 02 Mar 2010 | 4.90 
Apples | 03 Mar 2010 | 03 Mar 2010 | 2.50 
Apples | 05 Mar 2010 | 09 Mar 2010 | 4.90 
Apples | 10 Mar 2010 | 10 Mar 2010 | 2.50 
Apples | 11 Mar 2010 | 16 Mar 2010 | 4.90 
Apples | 17 Mar 2010 | 17 Mar 2010 | 2.50 
Apples | 18 Mar 2010 | 23 Mar 2010 | 4.90 
Apples | 24 Mar 2010 | 24 Mar 2010 | 2.50 
Apples | 25 Mar 2010 | 30 Mar 2010 | 4.90 
Apples | 31 Mar 2010 | 31 Mar 2010 | 2.50 

Qu'est-ce que s'il vous plaît être la meilleure approche pour y arriver?

Merci beaucoup à l'avance,

+2

Il serait plus facile de le faire comme une procédure stockée ou de mettre la logique dans votre application. –

+0

Il s'agit des données héritées d'une importation précédente d'un logiciel précédent. J'en ai juste besoin pour ranger cette table car il faut beaucoup trop d'enregistrements (une ligne par jour et produit). – Anonymouse

+0

Pourquoi n'y a-t-il pas de ligne pour le 4 mars, mais il y en a pour le 7 et le 8? –

Répondre

2

Cela devrait vous être très proche. Une fois que vous déterminez comment vous voulez gérer les dates manquantes, vous pouvez l'ajuster de manière appropriée:

SELECT 
    SD.Product, 
    SD.Price, 
    SD.StartDate, 
    MAX(ED.EndDate) AS EndDate 
FROM 
    dbo.PricesHist SD 
LEFT OUTER JOIN dbo.PricesHist ED ON 
    ED.Product = SD.Product AND 
    ED.Price = SD.Price 
LEFT OUTER JOIN dbo.PricesHist LD ON 
    LD.Product = SD.Product AND 
    LD.Price <> SD.Price AND 
    LD.EndDate < SD.StartDate 
LEFT OUTER JOIN dbo.PricesHist LMD ON 
    LMD.Product = SD.Product AND 
    LMD.Price = SD.Price AND 
    LMD.StartDate > ISNULL(LD.EndDate, '1900-01-01') AND 
    LMD.StartDate < SD.StartDate 
WHERE 
    NOT EXISTS (SELECT * FROM dbo.PricesHist MD WHERE MD.Product = SD.Product AND MD.Price <> SD.Price AND MD.StartDate BETWEEN SD.StartDate AND ED.EndDate) AND 
    LMD.Product IS NULL 
GROUP BY 
    SD.Product, 
    SD.Price, 
    SD.StartDate 
ORDER BY 
    SD.StartDate 
+0

Merci beaucoup. Fait le tour parfaitement! – Anonymouse

+0

@Tom H. cela vous dérangerait-il de m'aider sur cette question http://stackoverflow.com/questions/30378663/mysql-querying-aggregate-of-non-overlapping-dates? – exodream

Questions connexes