2009-09-04 5 views
0

은 내가 이전의 ID를 3 분 간격으로있는 모든 ID를 반환 할 이제 다음약간 복잡한 MySQL의 쿼리

id  timestamp 
------------------------------------- 
1  1247046037 
4  1247047437 
5  1247047438 
6  1247048738 

이있는 테이블이있다. 위의 예에서는 1,4,6을 반환합니다.

어떻게해야합니까? 종류 혼란. 나는 조인과 다른 것들을 가능한 한 많이 피하고 싶다.

UPDATE 죄송합니다, 나는 ID를 순차적하지 않을 수 있음을 언급하는 것을 잊었다 그래서 ID를 사용할 수 없습니다 = ID + 당신은 지금까지의 내가 할 수있는, 조인하지 않고이 작업을 수행 할 수 있도록하지 않을 1

답변

2

텔. 필요한 항목을 수행해야합니다.

select t1.id 
from mytable as t1 
    left join mytable as t2 on t1.id = (t2.id + 1) 
where t2.id is null or (t1.timestamp - 180) > t2.timestamp 

id 필드에 간격이있을 수있는 경우 행 번호 필드를 입력해야합니다. 이 규칙을 정기적으로 실행하는 경우 테이블에 자동 번호 필드를 추가하는 것이 더 효율적일 수 있습니다.

select t1.id 
from 
    (select mytable.*, @rownum:[email protected]+1 as rownum from mytable, (select @rownum:=0) r order by id) as t1 
    left join 
    (select mytable.*, @rownum2:[email protected]+1 as rownum from mytable, (select @rownum2:=0) r order by id) as t2 on t1.rownum = (t2.rownum + 1) 
where t2.id is null or (t1.timestamp - 180) > t2.timestamp 
+0

내가 accommo 업데이트 내 질문에 –

+0

대답을 업데이트 한 ID 필드의 틈을 메우십시오. – Richard

0

당신은 사용할 수있는 서로 옆에 두 개의 ID를 얻기 위해 널 자체를 조인 :

SELECT thing2.id 
FROM things AS thing1 
JOIN things AS thing2 ON thing1.id<thing2.id 
LEFT JOIN things AS nothing ON nothing.id BETWEEN thing1.id+1 AND thing2.id-1 
WHERE nothing.id IS NULL 
AND thing2.timestamp=thing1.timestamp+180 

즉. thing1과 thing2 사이에 id가있는 행이 없습니다.

는 (이 정확히 떨어져 3 분 거리에 있습니다 행을 얻을, 당신은 정말 떨어져 3 또는-분 이상 또는 3 또는-적은 분 거리에 있습니다 행을할지 여부는 질문에서 분명하지 않다.)

+0

change = to> = 작동하게하려면 – van

1

이 것 MSSQL에서 완벽하게 작동합니다. 당신이 id=0으로 행을하지 않고두면

SELECT  curr.* 
      --//,prev.* 
      --//,curr."timestamp" - prev."timestamp" 
FROM  @Table curr 
LEFT JOIN @Table prev 
     ON prev.ID = (SELECT TOP 1 prev_match.ID 
         FROM  @Table prev_match 
         WHERE  prev_match.ID < curr.ID 
         ORDER BY prev_match.ID DESC) 
WHERE  curr."timestamp" - prev."timestamp" >= 180 
     OR prev.ID IS NULL --// cover special case when there is no previous at all 

그러나, 나는 OR WHERE 조건에서 제거하고 INNER JOIN

+0

'TOP 1'은 MSSQL 관련 구문입니다. MySQL과 Postgres의 버전은 끝에 'LIMIT 1'입니다. 하지만 MySQL은 불행히도 하위 쿼리를 제한 할 수 없습니다. – bobince

+0

하위 쿼리에서'SELECT MAX (prev_match.ID) ...'를 대신 할 수 있습니까? – van

+0

그래, 작동해야합니다! 내가 왜 그렇게 생각하지 않았어? – bobince

0

LEFT JOIN을 변경합니다 : MySQL은이 타이 브레이커 쿼리를 처리 할 수 ​​있는지 흥미로운 일이 될 것이다 당신이 가입 피하고 싶은 경우에, 나는 당신이 대신 하위 쿼리를 사용할 수 있다고 생각하지만, 나는 그것에 대하여 추천 할 것입니다 너무 느린 것으로 기대 :

SELECT t.id 
FROM yourTable t 
WHERE t.timestamp - 
(SELECT t3.timestamp --This gives the time of the id before 
    FROM yourTable t3 
    WHERE id = 
    (SELECT ISNULL(MAX(t2.id),-1) --This gives the id before or -1 if first id. 
    FROM yourTable t2 
    WHERE t2.id < t.id) 
) 
> 180