2013-07-19 2 views
0

에서 연속 양수 내가 이런 "결과"라는 테이블이 있습니다MySQL의 쿼리 수의 열

 
ID -A- -B- -C- -D- -E- -F- 
1 100 -76 34 -45 54 65 
2 34 -43 57 -12 13 -21 
3 104 -76 34 -45 -3 43 
4 100 -76 -4 -45 54 65 
5 34 -43 57 -12 13 -21 
6 104 -76 34 -45 -3 43 

분명히 더 많은 데이터가 있습니다,하지만 난이 생각을하기에 충분하다고 생각합니다.

내가 얻으려고하는 것은 각 열의 연속적인 양수의 최대 값입니다.

그 대신 mysql 쿼리가 필요합니까?

이 책을 읽어 주셔서 감사합니다.

+2

"* 연속 양수의 최대 개수 *"는 무엇을 의미합니까? 예를 들어 줄 수 있습니까? 테이블은 특정 순서로 저장되지 않으므로 "* 연속 *"의 개념은'ORDER BY' 절이 없으면 잘못 정의됩니다. – eggyal

+0

당신은 이미 시도한 것과 당신의 결과는 무엇입니까? 원하는 결과와 어떻게 다른가요? – DevlshOne

+0

또한 정렬 순서를 결정하는 열이 필요합니다. – fancyPants

답변

0

여기에 아이디어가 있습니다. 열의 각 숫자에 대해 플래그를 추가하여 시퀀스의 시작인지 여부를 판별하십시오 (음수 다음에 오는 것임). 이 값의 누적 합계를 사용하여 "시퀀스 수"를 얻습니다. 그런 다음이 값의 최대 값을 얻으십시오. 하나의 열에 대한 코드를 보여 드리겠습니다 :

유일한 문제는 여러 수준의 상관 된 하위 쿼리가 필요한 구현입니다. 첫 번째는 SequenceStart를 할당하는 것입니다 : 당신이 두 값을 필요로하기 때문에

select r.*, rprev.A as prevA, rprev.B as prevB, rprev.C as prevC, rprev.D as prevD, 
     (case when (rprev.A < 0 or rprev.A is NULL) then 1 else 0 end) as ASeqStart, 
     (case when (rprev.B < 0 or rprev.B is NULL) then 1 else 0 end) as BSeqStart, 
     (case when (rprev.C < 0 or rprev.C is NULL) then 1 else 0 end) as CSeqStart, 
     (case when (rprev.D < 0 or rprev.D is NULL) then 1 else 0 end) as DSeqStart 
from (select r.*, 
      (select max(id) 
       from results r2 
       where r2.id < r.id 
      ) previd 
     from results r 
    ) r left outer join 
    results rprev 
    on r.previd = rprev.id; 

이제 누적 합계를 점점 까다 롭습니다. 불행히도, MySQL은 뷰에서 서브 쿼리를 허용하지 않습니다. 아래에서 동일한 쿼리를 사용할 수 있지만 그 결과가 테이블 TempSeq에 있다고 가정 해 봅시다. 그런 다음 각 값에 순서를 지정하려면 다음을 수행하십시오. 당신이 결과를 여러 번 집계하기 때문에

select ts.*, 
     sum(tsprev.ASeqStart) as ASeqId, 
     sum(tsprev.BSeqStart) as BSeqId, 
     sum(tsprev.CSeqStart) as CSeqId, 
     sum(tsprev.DSeqStart) as DSeqId 
from TempSeq ts join 
    TempSeq tsprev 
    on tsprev.id <= ts.id 
group by ts.id; 

다시 한번, 내가 결과가 다른 임시 테이블에 저장되어 있다고 가정하자, TempSeqId을 말한다.

select coalesce(max(seqlen), 0) 
from (select ASeqId, count(*) as seqlen 
     from TempSeqId 
     where a > 0 
    ) t 

a의 조건이 중복 보일 수 있습니다 : 여기에 대한 예입니다. 하지만 대부분의 시퀀스는 최종 음수로 끝날 것입니다. 이를 위해, 당신은 그 카운트에서 하나를 뺄 수 있습니다. 그러나 최종 시퀀스가 ​​끝나지 않을 수 있으며이를 적게 계산할 수 있습니다. 합병은 모든 값이 음수 인 경우입니다.

이 시점에서 데이터 구조가 idsequencename이고 한 행에 하나의 값이있는 행에 데이터 구조가 저장된 경우 실제로 쿼리를 실행할 수 있다고 가정 해 보겠습니다.

편집 :

위의 추론은 내가이 문제에 대해 생각하는 방법이다. MySQL에서는 변수를 사용하여 다르게 접근 할 수 있습니다. 코드는 훨씬 간단합니다 :

select MAX(APosCounter) as AMaxLen, 
     MAX(BPosCounter) as BMaxLen, 
     MAX(CPosCounter) as CMaxLen, 
     MAX(DPosCounter) as DMaxLen 
from (select r.*, 
      @APosCounter := if(A > 0, @APosCounter + 1, 0) as APosCounter, 
      @BPosCounter := if(B > 0, @BPosCounter + 1, 0) as BPosCounter, 
      @CPosCounter := if(C > 0, @CPosCounter + 1, 0) as CPosCounter, 
      @DPosCounter := if(D > 0, @DPosCounter + 1, 0) as DPosCounter 
     from results r cross join 
      (select @APosCounter := 0, @AMaxLen := 0, 
        @BPosCounter := 0, @BMaxLen := 0, 
        @CPosCounter := 0, @CMaxLen := 0, 
        @DPosCounter := 0, @DMaxLen := 0 
      end) const 
     order by id 
    ) r 

이 코드는 가변 논리를 사용하여 각 행의 "양의 시퀀스 길이"길이를 유지합니다. 그런 다음 데이터를 집계하여 최대 값을 얻습니다.

Here도 작동한다는 것을 입증하는 SQLFiddle입니다.

+0

TempSeq 테이블의 두 번째 select 쿼리에서이 "# 1052 - 필드 목록의 'ASeqStart'열이 모호합니다." –

+0

@AlexandrosTseros. . . 와우, 그것은 거기까지 작동했습니다;) 적절한 별칭을 추가했습니다. –

+0

마지막 쿼리에서이 "# 1054 - 알 수없는 열 'a'where '절" " –

0
select GREATEST(
sum(if (A <= 0, 0,1)), 
sum(if (B <= 0, 0,1)), 
sum(if (C <= 0, 0,1)), 
sum(if (D <= 0, 0,1)), 
sum(if (E <= 0, 0,1)), 
sum(if(F <= 0, 0,1)) 
) FROM RESULT 
+0

에 의해 주문 ID는 – jaczes

+0

@ 재치 ... 내가 뭘 얻었는지는 양수와 총액의 총 개수입니다. 내가 얻는 결과는 이것과 같습니다. SELECT COUNT (*) FROM results from a '0' –

+0

질문에 대한 오해가 있습니다. – jaczes