2013-07-02 2 views
0

날짜 당 약 1000 개의 ID 행이있는 날짜, id 및 값이 포함 된 테이블이 있습니다. 각 행의 백분위 수를 날짜별로 계산해야합니다. 하나의 날짜에 대해 백분위 수 순위에 다음 코드를 사용하고 있지만, 10 년이 넘는 일별 데이터는 날짜별로 실행하는 것이 매우 비효율적입니다. MySQL에서 공식화 될 수 있어야하지만 작동하게 만들지 못했습니다.그룹 별 MySQL 백분위 순위

Date ID Value 
date1 01 -7.2 
date1 02  0.6 
date2 01  1.2 
date2 02  3.8 

SELECT c.id, c.value, ROUND((
(@rank - rank)/@rank) *100, 2) AS rank 
FROM (
SELECT * , @prev := @curr , @curr := a.value, 
@nxtRnk := @nxtRnk + 1, 
@rank := IF(@prev = @curr , @rank , @nxtRnk) AS rank 
FROM (
SELECT id, value 
FROM temp 
WHERE date = '2013-06-28' 
) AS a, (

SELECT @curr := NULL , @prev := NULL , @rank :=0, @nxtRnk :=0 
) AS b 
ORDER BY value DESC 
) AS c 

그래서 기본적으로 나는 DISTINCT (날짜)를 선택하려면, 다음 각 날짜를 표 2에 결과를 작성하는 표 2 (...)에 삽입 덧붙일되는 SELECT, 위의를 수행합니다. 어떤 도움

감사합니다, 휴

답변

0

나는 마지막으로 임시 테이블을 사용하여 허용 솔루션을 개발했다. 최적의 솔루션이 아닐 수도 있지만 100 만 개 이상의 레코드 테이블에서 약 5 초 만에 작동합니다.

임시 테이블 (t1)에는 날짜와 날짜 행 수가 들어 있습니다. 제에서

세번째 선택 상술

또한 SELECT t1.date, t1.cnt, ID, T1의 값이 왼쪽에서 ON 임시 가입 (t1.date = temp.date)로 변경하고, 계산 위의 SELECT는 @rank 대신 c.cnt를 사용하도록 변경되었으며 @prevDate 변수는 날짜 변경시 순위 수를 재설정하기 위해 작성되었습니다.

이 문제를보고 해결책을 찾은 모든 사용자에게 감사드립니다.

0

저는 이것을 꽤 오랫동안 풀어 봤는데 다음 답을 찾았습니다. 솔직히 똑똑합니다. 또한 큰 테이블 (테이블을 사용할 때 약 5 mil의 레코드가 포함되어 있고 몇 초가 필요했습니다)에도 꽤 빠릅니다.

SELECT 
    CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(field_name ORDER BY 
    field_name SEPARATOR ','), ',', 95/100 * COUNT(*) + 1), ',', -1) AS DECIMAL) 
    AS 95th Per 
FROM table_name; 

table_name과 field_name을 테이블과 컬럼 이름으로 바꿀 수 있습니다.

자세한 내용은 Roland Bouman의 원본 게시물을 확인하십시오.