2013-07-16 2 views
0

다음과 같은 방식으로 mysql에서 결과를 얻으려고 애쓰는 중입니다. 나는 날짜와 단위 필드를 갖는 mysql db 테이블에 10 개의 레코드를 가지고있다. 나는 모든 날짜에 중고 단위를 얻을 필요가있다. 모든 기록에서 과거의 이전 장치와 함께 오늘 유닛을 추가, 다음과 같이단위 소비량을 날짜별로 가져옵니다.

테이블 구조 :

 
Date  Units 
---------- --------- 
10/10/2012 101 
11/10/2012 111 
12/10/2012 121 
13/10/2012 140 
14/10/2012 150 
15/10/2012 155 
16/10/2012 170 
17/10/2012 180 
18/10/2012 185 
19/10/2012 200 

원하는 출력 될 것입니다 : 어떤 도움을 이해할 수있을 것이다

 
Date  Units 
---------- --------- 
10/10/2012 101 
11/10/2012 10 
12/10/2012 10 
13/10/2012 19 
14/10/2012 10 
15/10/2012 5 
16/10/2012 15 
17/10/2012 10 
18/10/2012 5 
19/10/2012 15 

. 감사합니다

+0

단위와 units_used의 관계는 무엇입니까? – 7alhashmi

+0

@ 7alhashmi : units_used는 SQL 결과의 단위 별칭입니다. –

+0

나는 단위 열에서 unit_used를 얻는 방법을 의미합니까? – 7alhashmi

답변

2

결과를 얻는 데는 몇 가지 방법이 있습니다. 결과 집합에 여분의 열과 열의 순서로 살 수 있다면 다음과 같이 실행 가능한 접근 방식입니다.


하여 사용자 변수

SELECT d.Date 
    , IF(@prev_units IS NULL 
     ,@diff := 0 
     ,@diff := d.units - @prev_units 
     ) AS `Units_used` 
    , @prev_units := d.units AS `Units` 
    FROM (SELECT @prev_units := NULL) i 
    JOIN ( 
     SELECT t.Date, t.Units 
      FROM mytable t 
      ORDER BY t.Date, t.Units 
     ) d 

이 지정된 결과 집합을 반환하지만, 그뿐만 아니라 단위 칼럼을 포함한다. MySQL은 인라인 뷰를 처리하는 방식 (MySQL은 "파생 테이블"이라고 부름) 때문에 컬럼이 필터링 될 수는 있지만 비용이 더 많이 듭니다.

다른 컬럼을 제거하려면 다른 쿼리에서이를 감쌀 수 있습니다 ...

SELECT f.Date 
    , f.Units_used 
    FROM (
     query from above goes here 
     ) f 
ORDER BY f.Date 

그러나 다시, 그 열을 제거하는 두 번째 결과 집합 구체화의 추가 비용이 함께 제공됩니다.


A는 당신이 각 Date 값을 하나의 행이 보장되는 경우

, 중 하나 DATE로 저장하거나, 상수로 설정 timecomponent와 DATETIME 같은 반에 참여하여, 누락 된 날짜 값이 있다면

SELECT t.Date 
    , t.Units - s.Units AS Units_Used 
    FROM mytable t 
    LEFT 
    JOIN mytable s 
    ON s.Date = t.Date + INTERVAL -1 DAY 
    ORDER BY t.Date 

: 같은 자정 및 날짜 값에 빈틈이없는, 그리고 날짜로, DATE 또는 DATETIME 데이터 타입으로 점은 지정된 결과 집합을 반환 한 후 다른 쿼리를 정의 일치하는 이전 행이 없도록 간격 (간격)을 지정하면 Units_used는 NULL 값을가집니다.


상관 하위 쿼리

당신이 아니오 "실종 날짜"의 보증이없는 경우를 사용하여,하지만 당신은 더 이상 특정 날짜에 대한 행 하나 이상이 없다는 것을 보증을 가지고, 다음 다른 접근 방식 (성능면에서 일반적으로 더 비싼)는 상관 하위 쿼리 사용하는 것입니다

SELECT t.Date 
    , (t.Units - (SELECT s.Units 
         FROM mytable s 
        WHERE s.Date < t.Date 
        ORDER BY s.Date DESC 
        LIMIT 1) 
     ) AS Units_used 
    FROM mytable t 
ORDER BY t.Date, t.Units 
+0

귀하의 솔루션 덕분에 원하는 결과를 얻을 수있었습니다! –

1

spencer7593의 솔루션은 빠른 것입니다,하지만 당신은 또한 ... 이런 식으로 뭔가를 할 수

SELECT * FROM rolling; 
+----+-------+ 
| id | units | 
+----+-------+ 
| 1 | 101 | 
| 2 | 111 | 
| 3 | 121 | 
| 4 | 140 | 
| 5 | 150 | 
| 6 | 155 | 
| 7 | 170 | 
| 8 | 180 | 
| 9 | 185 | 
| 10 | 200 | 
+----+-------+ 

SELECT a.id,COALESCE(a.units - b.units,a.units) units 
    FROM 
(SELECT x.* 
     , COUNT(*) rank 
    FROM rolling x 
JOIN rolling y 
     ON y.id <= x.id 
GROUP 
    BY x.id 
) a  
LEFT 
JOIN 
(SELECT x.* 
     , COUNT(*) rank 
    FROM rolling x 
JOIN rolling y 
     ON y.id <= x.id 
GROUP 
    BY x.id 
) b 
ON b.rank= a.rank -1; 

    +----+-------+ 
    | id | units | 
    +----+-------+ 
    | 1 | 101 | 
    | 2 | 10 | 
    | 3 | 10 | 
    | 4 | 19 | 
    | 5 | 10 | 
    | 6 |  5 | 
    | 7 | 15 | 
    | 8 | 10 | 
    | 9 |  5 | 
    | 10 | 15 | 
    +----+-------+ 
+0

+1. 아주 좋아. 이는 또한 실행 가능한 접근법입니다. 기본적으로 semijoin을 사용하여 각 행에 대해 선행 행 수를 얻습니다 ('id' 값이있는 경우'id' 열과 함께 사용하여 ('존재하는 경우)'Date' 열을 사용할 수 있습니다 'Date' 시퀀스에서 오름차순입니다.) 그 카운트로, 우리는 본질적으로 각 행에 "행 순서"를 지정할 수 있습니다. 우리는 그것을 사용하여 앞의 행에 조인 할 수 있습니다. 아주 좋아. (이 접근법의 성능 단점은 큰 세트로 이루어지며, 세미 조인 세트의 크기가 커질 수 있으며 동일한 결과 세트가 여러 번 구체화되어야합니다. – spencer7593

+0

@ spencer7593 감사합니다. 질의는 오히려 비 제네릭이 될 수 있습니다! 명확히하기 : 값이 고유 한 경우 ID 열 대신에 날짜 열을 사용할 수 있습니다. 중요한 것은 값이 순차적이며 연속적 일 필요가 없다는 것입니다. – Strawberry

0

이렇게하면 원하는 결과를 얻을 수 있습니다. 내가 테이블을 어떻게 불러야할지 모르겠다. 그래서 나는 그것을 "tbltest"라고 명명했다. 테이블 날짜의 이름을 지정하는 것은 일반적으로 다른 개념 (함수, 데이터 형식 등)을 참조하므로 "fdate"로 이름을 바꾸는 것이 좋지 않습니다. 필드 이름이나 테이블 이름에 대문자를 사용하는 것은 성명을 데이터베이스에 덜 의존적이게하므로 나쁜 생각입니다 (일부 데이터베이스는 대소 문자를 구별하며 일부는 그렇지 않습니다).

SELECT 
    A.fdate, 
    A.units - coalesce(B.units, 0) AS units 
FROM 
    tbltest A left join tbltest B ON A.fdate = B.fdate + INTERVAL 1 DAY 
관련 문제