2013-08-08 3 views
0

나는이 문제가 해결하기 어려울 것이라고 생각합니다. 나는이 하나 내 DDBB의 테이블이 있습니다MySQL의 기간을 통한 증분 ​​수

ID  INTEGER(7) ZEROFILL NOT NULL 
MONTH VARCHAR(7) NOT NULL 
VALUE DOUBLE(20,2) 

내가 달성하기 위해 노력하고있어 횟수를 검색하는 방법은 통해입니다 : 다음과 같은 정의와

+----+--------+-------+ 
| ID | MONTH | VALUE | 
+----+--------+-------+ 
| 1 | 1-2000 | 20.00 | 
| 1 | 2-2000 | 21.00 | 
| 1 | 3-2000 | 7.00 | 
| 1 | 4-2000 | 8.00 | 
+----+--------+-------+ 

기간 {VALUE} 필드가 이전 값에서 증가했습니다. 위의 예에서 기간이 "1-2000"에서 "4-2000"이면 {VALUE}이 (가) [20.00-> 21.00, 7.00-> 8.00]의 두 번 증가했습니다.

결국, 나는 다음과 같은 출력을 갖고 싶은 것 :

내가 주요 문제로 지적하고있어 무엇
+----+------------+ 
| ID | NUM_OF_INC | 
+----+------------+ 
| 1 | 2   | 
+----+------------+ 

, 즉 {MONTH}입니다 (물론,이되지 않을 수 있음) DATE 유형 필드가 아닙니다.

이것을 달성 할 방법이 있습니까? 그 해결책은 모든 값을 얻은 다음 쿼리를 실행하는 엔진에서 하나씩 비교하는 것입니다.

+0

먼저 - 당신의'month' 평소 날짜 형식을 가질 수 없습니다 이유는 무엇입니까? –

+0

고객 요구 사항. 이상하지 않니? – Wolfchamane

+0

어리석은 클라이언트 요구 사항을 깨닫지 마십시오! 이 문제를 해결할 수도 있지만 따라야 할 것이 많고 해결할 수없는 것이 있습니다. 당신이 치과 의사라고 상상해보십시오. 환자가 공기 해머로 치아를 고칠 것을 요구합니다. 당신은 "아니오"라는 단어를 사용할 수 있습니다. –

답변

0

날짜 형식과 MySQL의 CTE가 부족하여 한 번 변환 할 수 없으므로 쿼리가 매우 자세하게 표시됩니다. 이것은 전체 범위를 검색하지만 동일한 패턴을 사용하여 범위 검사를 추가하는 것이 매우 쉽습니다.

SELECT a.id, COUNT(*) NUM_OF_INC 
FROM Table1 a 
JOIN Table1 b 
    ON a.id = b.id 
AND a.value < b.value 
AND STR_TO_DATE(CONCAT(a.`MONTH`, '-1'), '%c-%Y-%d') 
    < STR_TO_DATE(CONCAT(b.`MONTH`, '-1'), '%c-%Y-%d') 
LEFT JOIN Table1 c 
    ON a.id = c.id 
AND STR_TO_DATE(CONCAT(a.`MONTH`, '-1'), '%c-%Y-%d') 
    < STR_TO_DATE(CONCAT(c.`MONTH`, '-1'), '%c-%Y-%d') 
AND STR_TO_DATE(CONCAT(c.`MONTH`, '-1'), '%c-%Y-%d') 
    < STR_TO_DATE(CONCAT(b.`MONTH`, '-1'), '%c-%Y-%d') 
WHERE c.id IS NULL 
GROUP BY a.id; 

An SQLfiddle to test with.

슬프게도이 쿼리는 MONTH에있는 모든 인덱스를 사용하지 않습니다.

0

옵션 인 경우 MONTH의 데이터 유형을 계산 가능한 것으로 변경하는 것이 좋습니다. 지난 달 (월 - 1)에 가입하고 차이를> 0으로 선택할 수 있습니다.

SELECT 
    t1.ID, count(*) 
    FROM 
    Entity t1 
    INNER JOIN Entity t2 
    ON t1.ID = t2.ID 
     AND t2.MONTH = t1.MONTH - 1 
    WHERE 
    t1.VALUE - t2.VALUE > 0 
    AND t1.MONTH BETWEEN :beginDate AND :endDate 
    GROUP BY t1.ID 

데이터 유형을 변경할 수없는 경우 다음을 선택할 수 있습니다. t1.MONTH BETWEEN :beginDate AND :endDate뿐만 아니라

DATE_FORMAT(
    SUBDATE(
    STR_TO_DATE(CONCAT(t1.MONTH, "-1"), "%c-%Y-%d"), 
    INTERVAL 1 MONTH), 
    "%c-%Y") 

: 당신은 어떤 MySQL의 기능과 t1.MONTH - 1을 변경해야의

STR_TO_DATE(CONCAT(t1.MONTH, "-1"), "%c-%Y-%d") 
    BETWEEN :beginDate AND :endDate 
관련 문제