2010-04-12 2 views
1

나는 제품이에 간단하게 테이블이있을 때 :보기 특정 기간를 선택하거나, 최신 널

create table product(id int primary key identity, productid int, year int, quarter int, price money) 

일부 샘플 데이터를 :

insert into product select 11, 2010, 1, 1.11 
insert into product select 11, 2010, 2, 2.11 
insert into product select 11, 2010, 3, 3.11 
insert into product select 12, 2010, 1, 1.12 
insert into product select 12, 2010, 2, 2.12 
insert into product select 13, 2010, 1, 1.13 

가격은 매 분기마다 변경 될 수 있습니다 하지만, 모든 제품이 매 분기마다 새로운 가격을받는 것은 아닙니다. 이제는 분기별로 데이터를 복제하여 가격을 동일하게 유지할 수 있지만보기를 사용하고 싶습니다.

(예 : 분기 2의 가격을 반환하는 데 사용할 수있는보기를 만들려면 어떻게해야합니까? 나는 이것이 현재 (= 최신) 가격 돌아 서면으로 작성했습니다 :

CREATE VIEW vwCurrentPrices AS 
    SELECT * 
    FROM 
    (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY productid ORDER BY year DESC, quarter DESC) AS Ranking   
     FROM product 
    ) p 
    WHERE p.Ranking = 1 

은 내가 어떤 실험 후 select * from vwProduct where quarter = 2

답변

1
CREATE TABLE quarters ([year] int, [quarter] int, PRIMARY KEY([year],[quarter])) 

INSERT INTO quarters ([year], [quarter]) 
SELECT 2000 + number/4 [year], number%4 + 1 [quarter] 
FROM master.dbo.spt_values 
WHERE type = 'P' AND number BETWEEN 0 and 199 

CREATE VIEW pricing WITH SCHEMABINDING AS 
WITH pricerank AS 
    (SELECT q.[year], q.[quarter], p.productid, p.price, 
    p.[year] effectiveyear, p.[quarter] effectivequarter, 
    ROW_NUMBER() OVER (PARTITION BY p.productid, 
    q.[year], q.[quarter] ORDER BY p.[year] DESC, p.[quarter] DESC) AS ranking 
    FROM dbo.quarters q INNER JOIN dbo.product p 
    ON p.[year] = q.[year] AND p.[quarter] <= q.[quarter] OR p.[year] < q.[year] 
    WHERE q.[year] <= YEAR(GETDATE())) 
SELECT [year], [quarter], productid, price 
FROM pricerank 
WHERE ranking = 1 

CREATE UNIQUE CLUSTERED INDEX IX_pricing ON pricing([year],[quarter],productid) 
+0

아주 좋은! 예상대로 작동합니다. 감사합니다 – edosoft

+0

보기가 잘 수행되지 않습니다. 나는 두려워합니다. 평균 3 기간의 데이터를 가진 약 8.000 개의 제품으로 모든 레코드를 선택하는 데 약 30 초가 소요됩니다. 내가 게시 한 UDF는 1을 사용합니다. – edosoft

+1

영구적 인 [숙소] 테이블을 사용하여 코드를 추가로 최적화했습니다. 제품에 대한 색인을 추가 할 수도 있습니다 ([year], [quarter]). –

0

같은 쿼리를 사용할 수 있도록보기를 만들 싶습니다을 나는 UDF 함께했다 그게 내 원하는 결과를 달성. 원하는 날짜 (quarter + year) 이전에 모든 가격을 먼저 필터링 한 다음 가장 높은 rownumber, 즉 최신 결과를 취합니다.

CREATE FUNCTION dbo.fTest(@year int, @quarter int) 
RETURNS TABLE 
AS 

return 
(
    select * from 
    (
     SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY productid ORDER BY year DESC, quarter DESC) AS rownum 
     FROM product 
     where DateAdd(month, (quarter - 1) * 3, DateAdd(Year, year - 1900, 0)) <= DateAdd(month, (@quarter - 1) * 3, DateAdd(Year, @year - 1900, 0)) 
    ) p 
    where rownum = 1 
)