2011-12-08 4 views
1

내가 테이블 t이없는 X 날짜 이후에, 그리고 다른 테이블의 경우, X 일 이전, 값마다 가장 최근의 선택 :MySQL은

id, timestamp 

이 여러 ID 값이 있으며, 여러 행이를 공유 할 수 주어진 이드.

x 날짜 이전에 id가 발견되지 않고 id가 y 표에서 발견되지 않는 경우에만 각 id에 대해 x 날짜 이전의 가장 최근 행을 선택하려고합니다.

내가 단, x 일 전에 모든를 선택할 수 있습니다 : 날짜 = 5 :

SELECT * FROM t WHERE timestamp < :date 

내가하지 최근 점점 만 가장 최근의 ID를 얻기 위해 시도 -하지만, ID 당 1 개 행을 반환 :

저는 GROUP BY가 많은 데이터로 인해 작업 속도를 늦출 것이라고 우려하고 있습니다.

CREATE TABLE IF NOT EXISTS `t` (
    `id` int(2) NOT NULL, 
    `timestamp` int(2) NOT NULL 
) 
INSERT INTO `t` (`id`, `timestamp`) VALUES 
(1, 1), 
(1, 4), 
(2, 3), 
(2, 1), 
(2, 6), 
(3, 4), 
(3, 2); 

CREATE TABLE IF NOT EXISTS `y` (
    `id` int(2) NOT NULL, 
    `timestamp` int(2) NOT NULL 
) 
INSERT INTO `y` (`id`, `timestamp`) VALUES 
(3, 1); 

은 행 (1,4) 만 ...

감사를 반환하는 상대 :

는 여기에 몇 가지 샘플 DB 데이터입니다!

+0

"timestamp value에"(1,4) 만 "결과가 필요합니까? –

+0

즉'SELECT * FROM t WHERE timestamp <: date' - 당신의 예제는': date'입니까? –

+0

이 예제에서는 : date로 5를 사용합니다! – cars

답변

2

당신은 다른 테이블에서 데이터를 비교하기 위해 LEFT JOIN을 (오히려 정렬보다) 최신 시간을 얻기 위해 MAX로 선택해야하고, 오직 적절한 데이터를 선택에 BY 그룹에 인수로 HAVING.

SELECT t.id, MAX(t.timestamp) AS latest_timestamp 
FROM t 
LEFT JOIN y on t.id = y.id 
WHERE y.id IS NULL 
GROUP BY t.id 
HAVING latest_timestamp <= :date 

GROUP BY를 할 때 집계 함수를 사용하여 선택할 수 있습니다. 여기서 MAX는 그룹의 모든 행에서 해당 열에 대한 최대 값을 반환합니다 (id로 그룹화 했으므로 각 id에 대해 최대 타임 스탬프를 반환합니다). 그러나 HAVING이 오는 날짜 인 — (HAVING은 본질적으로 GROUP BY 집계의 WHERE) 이후에 타임 스탬프가없는 요소 만 선택하려고합니다. 마지막으로 테이블 y에있는 요소를 선택하지 않으려 고합니다. 따라서 LEFT JOIN 테이블 y를 가져오고 테이블 y의 해당 행이 존재하지 않는 행만 선택합니다 (즉, 해당 ID는 테이블 y에 존재하지 않습니다). 일반 WHERE를 사용하여이 작업을 수행합니다.

업데이트 :이 작업을 효율적으로 수행하려면 적절한 열에 인덱스를 추가하기 만하면됩니다. 이 경우 t.id, t.timestampy.id에 대한 색인을 추가 할 수 있습니다. dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html을 참조하십시오.

+0

우아하고 고마워요! 더 효율적으로하기 위해 조사 할 곳이 있습니까? – cars

+0

효율적으로 만들려면 적절한 열에 인덱스를 추가하기 만하면됩니다 (이 경우에는't.id','t.timestamp' 및'y.id'에 대한 인덱스를 추가하고 싶을 것입니다). –

+0

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html 참조 –