题
有必须写这个查询的一个更好的方法。
我想选择所有的一对日期之间的数据。理想情况下,结果集的第一个和最后一个行会是那些在WHERE子句中specifed。如果不存在那些行中,我想的行前述和以下所请求的范围内。
的示例:
如果我的数据是:
...
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,日期时间,和索引(param_id,日期时间)
解决方案
首先,确保你有一个综合在(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
操作者被捕获将失败,并且主查询将返回任何行的。
不隶属于 StackOverflow