2010-02-22 4 views
1

다양한 제품의 가격을 추적하는 응용 프로그램이 있습니다. 특정 제품의 가격은 하루 중 언제든지 바뀔 수 있으며 정기적으로 변경되지는 않습니다. 시간 경과에 따른 제품의 모든 가격에 대한 기록을 담은 PriceHistory 테이블이 있습니다. 응용 프로그램 사용자는 시간과 날짜를 선택하고 그 당시의 가격을 확인할 수 있습니다.주어진 DateTime 전에 가장 최근 레코드 두 개를 가져 오기위한 MySQL 쿼리

SELECT A.* 
FROM `PriceHistory` A 
INNER JOIN (
    SELECT `BrandKey`, `LocationKey`, `ProductKey`, max(`EffectiveDateTime`) AS MaxUpdateDate 
    FROM `PriceHistory` 
    WHERE `EffectiveDateTime` <= '2010-02-22 12:00:00' 
    GROUP BY `BrandKey`, `LocationKey`, `ProductKey` 
) AS B ON 
A.`BrandKey` = B.`BrandKey` 
AND A.`LocationKey` = B.`LocationKey` 
AND A.`ProductKey` = B.`ProductKey` 
AND A.`EffectiveDateTime` = B.MaxUpdateDate 

가 지금은 그 가격이 발효 할 때 가격이 변경 얼마나 많은 사용자를 보여줄 수 있어야합니다 : 어떤 특정 날짜와 시간에 모든 제품에 대해 "현재"가격을 얻기 위해이 같은 쿼리를 사용 . 그래서 나는 단지 하나의 시간 대신에 가장 최근의 두 가지 가격을 선택해야합니다. 나는 꽤 난처한 처지이다. 몇 가지 시도했는데 내 시도 조인이 합법적이지 않기 때문에 SQL 오류가 발생했습니다. 어떤 도움을 주시면 감사하겠습니다.

나는 모든 제품을 반복 할 수 있고 가장 최근의 두 가지 가격을 얻을 수 있지만 제품 350 개와 가격 행 75,000 개에 약 10 초가 걸린다. 필자는 하나의 쿼리에서 모든 제품을 반드시 필요로하지는 않지만 각 제품에 대한 쿼리를 실행하는 것은 충분히 빠르지 않을 것입니다.

답변

2

내가이 개 선택으로 그것을 깰 것 ..

1 - 선택 최대 (EffectiveDateTime) ... 주가 추이에서 EffectiveDateTime < = '2010-02-22 12시 0분 0초'

2 단계)이 경우 priceHistory 테이블에 숫자 (autoinc type) PK가 있어야합니다. 존재하지 않으면 추가하십시오. PriceHistoryID

라고이 열을 가정

파트 A) $의 ignoreRows

파트 B) 데이터의 가장 최근의 설정을 무시하고 최대 날짜를 얻을 수를 마지막 쿼리에서 모든 숫자 PK 년대를 잡아 및 VAR로를 내파하는 당신은 반대하고 싶다. 즉, 가장 최근의 데이터를 마지막으로 두 번째를 얻는다.

주가 추이 EffectiveDateTime < = '2010-02-22 12시 0분 0초'AND priceHistoryID NOT IN ($ ignoreRows)

주에서 선택 최대 (EffectiveDateTime) ... 당신은 단지 1이있는 경우 가격 내역의 데이터 포인트는 1-1과 일치하지 않을 수도 있지만 코드에서 수정할 수있는 것은 비교적 사소한 것입니다 ...

0

LIMIT 2으로 EffectiveDateTime 순으로 정렬하고 DESC 순으로 정렬하는 쿼리가 필요합니다.

SELECT A.* 
FROM `PriceHistory` A 
WHERE <clauses for selecting a product and brand go here> 
ORDER BY `EffectiveDateTime` DESC 
LIMIT 2 
+0

이렇게하면 두 줄만 표시됩니다. 약 350 개의 제품이 있으므로 700 개의 행이나 350 개의 넓은 행을 찾고 있습니다. 나는 조금 더 명확하게하기 위해 나의 질문을 편집했다. –

1

auto_increment 열이 복합 키.이 열은 동일한 값을 갖는 모든 행의 계수기 역할을합니다.

EG.

v1,v2,v3,1 
v1,v2,v3,2 
v1,v2,v4,1 
... 

같은 BrandKey 모든 항목을 평가하기 위해 역사 테이블에서 만들어진 임시 테이블이 사용할 수 LocationKey,의 Productkey 내림차순 날짜 값에.

create temporary table ph ( 
    `BrandKey` varchar(10), 
    `LocationKey` varchar(10), 
    `ProductKey` varchar(10), 
    `EffectiveDateTime`datetime, 
    rank int not null auto_increment, 
    primary key(BrandKey, LocationKey, ProductKey, rank); 

insert into ph 
    select `BrandKey`, `LocationKey`, `ProductKey`, `EffectiveDateTime`, NULL 
    FROM `PriceHistory` 
    WHERE `EffectiveDateTime` <= '2010-02-22 12:00:00' 
    order by EffectiveDateTime desc; 

delete from ph where rank > 2; 

이 임시 테이블은 이제 다음 easliy 당신의 가격 테이블에 대해 조인 할 수 있습니다 1 또는 2 BrandKey 당 행, LocationKey, ProductKey을 포함 - 자기 (왼쪽) 현재를 모두 포함해야하는 경우 참여를 사용하여 동일한 행에있는 이전 가격.

+0

재미있는 카운터 사용 – Zak

관련 문제