1

このクエリを書くためのより良い方法があるはずです。

日付のペアの間のすべてのデータを選択したいと思います。理想的には、結果セットの最初と最後の行は、WHERE句で指定された行になります。それらの行が存在しない場合は、要求された範囲の前後の行が必要です。

例:

私のデータが次の場合:

...
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)にインデックスがあります

4

2 に答える 2

3

私はこう言います:

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演算子は失敗し、メイン クエリは行をまったく返しません。

于 2009-03-13T18:11:05.783 に答える
2

まず、複合インデックスがあることを確認してください(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

于 2009-03-16T12:59:02.883 に答える