WHERE句で指定されたものを超えてクエリを展開する
-
22-07-2019 - |
質問
このクエリを記述するためのより良い方法が必要です。
日付のペアの間のすべてのデータを選択したい。理想的には、結果セットの最初と最後の行は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)にインデックスがあります
解決
まず、(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')
チェックしただけで、 200,000
行のサンプルテーブルに対して 1.215 ms
で実行されます
他のヒント
私はこう言います:
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
演算子は失敗し、メインクエリは行をまったく返しません。
所属していません StackOverflow