문제

이 쿼리를 작성하는 더 나은 방법이 있어야합니다.

한 쌍의 날짜 사이에 모든 데이터를 선택하고 싶습니다. 이상적으로 결과 세트의 첫 번째 및 마지막 행은 WHERE 절에 지정된 행입니다. 그 행이 존재하지 않으면, 나는 요청 된 범위에 따라 행을 앞서서, 그리고 나는 행을 예상하고 싶다.

An example:

내 데이터가 :

...
135321, 20090311 10:15:00
135321, 20090311 10:45:00
135321, 20090311 11:00:00
135321, 20090311 11:15:00
135321, 20090311 11:30:00
135321, 20090311 12:30:00
...

그리고 쿼리는 다음과 같습니다.

    SELECT * 
    FROM data_bahf 
    WHERE param_id = 135321 
    AND datetime >= '20090311 10:30:00' 
    AND datetime <= '20090311 12:00:00'

반환 된 데이터가 10:15에 행과 12:30의 행을 포함시키기를 원합니다. Where 절을 엄격하게 충족시키는 것만이 아닙니다.

이것은 내가 생각해 낸 최고입니다.

SELECT * FROM (
    SELECT * 
    FROM data_bahf 
    WHERE param_id = 135321 
    AND datetime > '20090311 10:30:00' 
    AND datetime < '20090311 12:00:00'

    UNION

    (
        SELECT * FROM data_bahf 
        WHERE param_id = 135321 
        AND datetime <= '20090311 10:30:00' 
        ORDER BY datetime desc
        LIMIT 1
    )

    UNION

    (
        SELECT * FROM data_bahf 
        WHERE param_id = 135321 
        AND datetime >= '20090311 12:00:00'
        ORDER BY datetime asc
        LIMIT 1
    )
) 
AS A
ORDER BY datetime

(Select *의 사용을 무시하십시오)

편집 : param_id, datetime 및 (param_id, dateTime)에 대한 색인이 있습니다.

도움이 되었습니까?

해결책

먼저, 당신이 가지고 있는지 확인하십시오 합성물 색인 켜기 (param_id, datetime)

둘째, 다음과 같은 쿼리 :

SELECT  *
FROM    data_bahf
WHERE   param_id = 135321
        AND datetime BETWEEN
        COALESCE(
        (
        SELECT  MAX(datetime)
        FROM    data_bahf
        WHERE   param_id = 135321
              AND datetime <= '2009-01-01 00:00:00'
        ), '0001-01-01')
        AND 
        COALESCE(
        (
        SELECT  MIN(datetime)
        FROM    data_bahf
        WHERE   param_id = 135321
              AND datetime >= '2009-01-02 00:00:00'
        ), '9999-01-01')

방금 확인하면 들어옵니다 1.215 ms 샘플 테이블의 경우 200,000

다른 팁

이렇게 말하고 싶습니다 :

SELECT 
  o.* 
FROM 
  data_bahf o
WHERE 
  o.param_id = 135321 
  AND o.datetime BETWEEN
  ISNULL(
    (
      SELECT   MAX(datetime) 
      FROM     data_bahf i
      WHERE    i.param_id = 135321 AND i.datetime <= '20090311 10:30:00'
    ),
    '0001-01-01 00:00:00'
  )
  AND
  ISNULL(
    (
      SELECT   MIN(datetime) 
      FROM     data_bahf i
      WHERE    i.param_id = 135321 AND i.datetime >= '20090311 12:00:00'
    ),
    '9999-12-31 23:59:59'
  )

편집 : 폴백 추가.
하위 쿼리와 일치하는 행이 없으면 NULL 값을 잡아야합니다 ISNULL() 아니면 그 BETWEEN 연산자가 실패하고 기본 쿼리는 전혀 행을 반환하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top